383 lines
21 KiB
HTML
383 lines
21 KiB
HTML
<head>
|
|
<title>thread(3) - Plan 9 from User Space</title>
|
|
<meta content="text/html; charset=utf-8" http-equiv=Content-Type>
|
|
</head>
|
|
<body bgcolor=#ffffff>
|
|
<table border=0 cellpadding=0 cellspacing=0 width=100%>
|
|
<tr height=10><td>
|
|
<tr><td width=20><td>
|
|
<tr><td width=20><td><b>THREAD(3)</b><td align=right><b>THREAD(3)</b>
|
|
<tr><td width=20><td colspan=2>
|
|
<br>
|
|
<p><font size=+1><b>NAME </b></font><br>
|
|
|
|
<table border=0 cellpadding=0 cellspacing=0><tr height=2><td><tr><td width=20><td>
|
|
|
|
alt, chancreate, chanfree, chaninit, chanprint, chansetname, mainstacksize,
|
|
proccreate, procdata, recv, recvp, recvul, send, sendp, sendul,
|
|
nbrecv, nbrecvp, nbrecvul, nbsend, nbsendp, nbsendul, threadcreate,
|
|
threaddata, threadexec, threadexecl, threadexits, threadexitsall,
|
|
threadgetgrp, threadgetname, threadint,
|
|
threadintgrp, threadkill, threadkillgrp, threadmain, threadnotify,
|
|
threadid, threadpid, threadsetgrp, threadsetname, threadsetstate,
|
|
threadspawn, threadwaitchan, yield – thread and proc management<br>
|
|
|
|
</table>
|
|
<p><font size=+1><b>SYNOPSIS </b></font><br>
|
|
|
|
<table border=0 cellpadding=0 cellspacing=0><tr height=5><td></table>
|
|
|
|
|
|
<table border=0 cellpadding=0 cellspacing=0><tr height=2><td><tr><td width=20><td>
|
|
|
|
<tt><font size=+1>#include <u.h><br>
|
|
#include <libc.h><br>
|
|
#include <thread.h><br>
|
|
#define CHANEND 0<br>
|
|
#define CHANSND 1<br>
|
|
#define CHANRCV 2<br>
|
|
#define CHANNOP 3<br>
|
|
#define CHANNOBLK 4<br>
|
|
typedef struct Alt Alt;<br>
|
|
struct Alt {<br>
|
|
|
|
<table border=0 cellpadding=0 cellspacing=0><tr height=2><td><tr><td width=20><td>
|
|
|
|
Channel *c;<br>
|
|
void *v;<br>
|
|
int op;<br>
|
|
Channel **tag;<br>
|
|
int entryno;<br>
|
|
char *name;<br>
|
|
|
|
</table>
|
|
};<br>
|
|
|
|
<table border=0 cellpadding=0 cellspacing=0><tr height=5><td></table>
|
|
|
|
void threadmain(int argc, char *argv[])<br>
|
|
int mainstacksize<br>
|
|
int proccreate(void (*fn)(void*), void *arg, uint stacksize)<br>
|
|
int threadcreate(void (*fn)(void*), void *arg, uint stacksize)<br>
|
|
void threadexits(char *status)<br>
|
|
void threadexitsall(char *status)<br>
|
|
void yield(void)<br>
|
|
int threadid(void)<br>
|
|
int threadgrp(void)<br>
|
|
int threadsetgrp(int group)<br>
|
|
int threadpid(int id)<br>
|
|
int threadint(int id)<br>
|
|
int threadintgrp(int group)<br>
|
|
int threadkill(int id)<br>
|
|
int threadkillgrp(int group)<br>
|
|
void threadsetname(char *name)<br>
|
|
char* threadgetname(void)<br>
|
|
void** threaddata(void)<br>
|
|
void** procdata(void)<br>
|
|
int chaninit(Channel *c, int elsize, int nel)<br>
|
|
Channel* chancreate(int elsize, int nel)<br>
|
|
void chanfree(Channel *c)<br>
|
|
int alt(Alt *alts)<br>
|
|
int recv(Channel *c, void *v)<br>
|
|
void* recvp(Channel *c)<br>
|
|
ulong recvul(Channel *c)<br>
|
|
int nbrecv(Channel *c, void *v)<br>
|
|
void* nbrecvp(Channel *c)<br>
|
|
ulong nbrecvul(Channel *c)<br>
|
|
int send(Channel *c, void *v)<br>
|
|
int sendp(Channel *c, void *v)<br>
|
|
int sendul(Channel *c, ulong v)<br>
|
|
int nbsend(Channel *c, void *v)<br>
|
|
int nbsendp(Channel *c, void *v)<br>
|
|
int nbsendul(Channel *c, ulong v)<br>
|
|
int chanprint(Channel *c, char *fmt, ...)<br>
|
|
int threadspawn(int fd[3], char *file, char *args[])<br>
|
|
int threadexecl(Channel *cpid, int fd[3], char *file, ...)<br>
|
|
int threadexec(Channel *cpid, int fd[3], char *file, char *args[])<br>
|
|
Channel* threadwaitchan(void)<br>
|
|
int threadnotify(int (*f)(void*, char*), int in)<br>
|
|
</font></tt>
|
|
</table>
|
|
<p><font size=+1><b>DESCRIPTION </b></font><br>
|
|
|
|
<table border=0 cellpadding=0 cellspacing=0><tr height=5><td></table>
|
|
|
|
|
|
<table border=0 cellpadding=0 cellspacing=0><tr height=2><td><tr><td width=20><td>
|
|
|
|
The thread library provides parallel programming support similar
|
|
to that of the languages Alef and Newsqueak. Threads and procs
|
|
occupy a shared address space, communicating and synchronizing
|
|
through <i>channels</i> and shared variables.
|
|
<table border=0 cellpadding=0 cellspacing=0><tr height=5><td></table>
|
|
|
|
A <i>proc</i> is a Plan 9 process that contains one or more cooperatively
|
|
scheduled <i>threads</i>. Programs using threads must replace <i>main</i> by
|
|
<i>threadmain</i>. The thread library provides a <i>main</i> function that sets
|
|
up a proc with a single thread executing <i>threadmain</i> on a stack
|
|
of size <i>mainstacksize</i> (default eight kilobytes). To set
|
|
<i>mainstacksize</i>, declare a global variable initialized to the desired
|
|
value (<i>e.g.</i>, <tt><font size=+1>int mainstacksize = 1024</font></tt>).
|
|
<table border=0 cellpadding=0 cellspacing=0><tr height=5><td></table>
|
|
|
|
<i>Threadcreate</i> creates a new thread in the calling proc, returning
|
|
a unique integer identifying the thread; the thread executes <i>fn(arg)</i>
|
|
on a stack of size <i>stacksize</i>. Thread stacks are allocated in shared
|
|
memory, making it valid to pass pointers to stack variables between
|
|
threads and procs. <i>Proccreate</i> creates a new proc,
|
|
and inside that proc creates a single thread as <i>threadcreate</i> would,
|
|
returning the id of the created thread. Be aware that the calling
|
|
thread may continue execution before the newly created proc and
|
|
thread are scheduled. Because of this, <i>arg</i> should not point to
|
|
data on the stack of a function that could return before the
|
|
new process is scheduled.
|
|
<table border=0 cellpadding=0 cellspacing=0><tr height=5><td></table>
|
|
|
|
<i>Threadexits</i> terminates the calling thread. If the thread is the
|
|
last in its proc, <i>threadexits</i> also terminates the proc, using
|
|
<i>status</i> as the exit status. <i>Threadexitsall</i> terminates all procs
|
|
in the program, using <i>status</i> as the exit status.
|
|
<table border=0 cellpadding=0 cellspacing=0><tr height=5><td></table>
|
|
|
|
When the last thread in <i>threadmain</i>’s proc exits, the program will
|
|
appear to its parent to have exited. The remaining procs will
|
|
still run together, but as a background program.
|
|
<table border=0 cellpadding=0 cellspacing=0><tr height=5><td></table>
|
|
|
|
The threads in a proc are coroutines, scheduled nonpreemptively
|
|
in a round-robin fashion. A thread must explicitly relinquish
|
|
control of the processor before another thread in the same proc
|
|
is run. Calls that do this are <i>yield</i>, <i>proccreate</i>, <i>threadexec</i>,
|
|
<i>threadexecl</i>, <i>threadexits</i>, <i>threadspawn</i>, <i>alt</i>, <i>send</i>, and <i>recv</i> (and
|
|
the
|
|
calls related to <i>send</i> and <i>recv</i>--see their descriptions further on).
|
|
Procs are scheduled by the operating system. Therefore, threads
|
|
in different procs can preempt one another in arbitrary ways and
|
|
should synchronize their actions using <tt><font size=+1>qlocks</font></tt> (see <a href="../man3/lock.html"><i>lock</i>(3)</a>) or
|
|
channel communication. System calls such as <a href="../man3/read.html"><i>read</i>(3)</a>
|
|
block the entire proc; all threads in a proc block until the system
|
|
call finishes.
|
|
<table border=0 cellpadding=0 cellspacing=0><tr height=5><td></table>
|
|
|
|
As mentioned above, each thread has a unique integer thread id.
|
|
Thread ids are not reused; they are unique across the life of
|
|
the program. <i>Threadid</i> returns the id for the current thread. Each
|
|
thread also has a thread group id. The initial thread has a group
|
|
id of zero. Each new thread inherits the group id of the
|
|
thread that created it. <i>Threadgrp</i> returns the group id for the
|
|
current thread; <i>threadsetgrp</i> sets it. <i>Threadpid</i> returns the pid
|
|
of the Plan 9 process containing the thread identified by <i>id</i>,
|
|
or –1 if no such thread is found.
|
|
<table border=0 cellpadding=0 cellspacing=0><tr height=5><td></table>
|
|
|
|
<i>Threadint</i> interrupts a thread that is blocked in a channel operation
|
|
or system call. <i>Threadintgrp</i> interrupts all threads with the given
|
|
group id. <i>Threadkill</i> marks a thread to die when it next relinquishes
|
|
the processor (via one of the calls listed above). If the thread
|
|
is blocked in a channel operation or system call, it is
|
|
also interrupted. <i>Threadkillgrp</i> kills all threads with the given
|
|
group id. Note that <i>threadkill</i> and <i>threadkillgrp</i> will not terminate
|
|
a thread that never relinquishes the processor.
|
|
<table border=0 cellpadding=0 cellspacing=0><tr height=5><td></table>
|
|
|
|
Primarily for debugging, threads can have string names associated
|
|
with them. <i>Threadgetname</i> returns the current thread’s name; <i>threadsetname</i>
|
|
sets it. The pointer returned by <i>threadgetname</i> is only valid until
|
|
the next call to <i>threadsetname</i>.
|
|
<table border=0 cellpadding=0 cellspacing=0><tr height=5><td></table>
|
|
|
|
Also for debugging, threads have a string state associated with
|
|
them. <i>Threadsetstate</i> sets the state string. There is no <i>threadgetstate</i>;
|
|
since the thread scheduler resets the state to <tt><font size=+1>Running</font></tt> every time
|
|
it runs the thread, it is only useful for debuggers to inspect
|
|
the state.
|
|
<table border=0 cellpadding=0 cellspacing=0><tr height=5><td></table>
|
|
|
|
<i>Threaddata</i> returns a pointer to a per-thread pointer that may
|
|
be modified by threaded programs for per-thread storage. Similarly,
|
|
<i>procdata</i> returns a pointer to a per-proc pointer.
|
|
<table border=0 cellpadding=0 cellspacing=0><tr height=5><td></table>
|
|
|
|
<i>Threadexecl</i> and <i>threadexec</i> are threaded analogues of <i>exec</i> and
|
|
<i>execl</i> (see <a href="../man3/exec.html"><i>exec</i>(3)</a>); on success, they replace the calling thread
|
|
and invoke the external program, never returning. (Unlike on Plan
|
|
9, the calling thread need not be the only thread in its proc--the
|
|
other threads will continue executing.) On error, they return
|
|
–1. If <i>cpid</i> is not null, the pid of the invoked program will be
|
|
sent along <i>cpid</i> (using <i>sendul</i>) once the program has been started,
|
|
or –1 will be sent if an error occurs. <i>Threadexec</i> and <i>threadexecl</i>
|
|
will not access their arguments after sending a result along <i>cpid</i>.
|
|
Thus, programs that malloc the <i>argv</i> passed to <i>threadexec
|
|
</i>can safely free it once they have received the <i>cpid</i> response.
|
|
|
|
<table border=0 cellpadding=0 cellspacing=0><tr height=5><td></table>
|
|
|
|
<i>Threadexecl</i> and <i>threadexec</i> will duplicate (see <a href="../man3/dup.html"><i>dup</i>(3)</a>) the three
|
|
file descriptors in <i>fd</i> onto standard input, output, and error
|
|
for the external program and then close them in the calling thread.
|
|
Beware of code that sets<br>
|
|
|
|
<table border=0 cellpadding=0 cellspacing=0><tr height=2><td><tr><td width=20><td>
|
|
|
|
<tt><font size=+1>fd[0] = 0;<br>
|
|
fd[1] = 1;<br>
|
|
fd[2] = 2;<br>
|
|
|
|
<table border=0 cellpadding=0 cellspacing=0><tr height=5><td></table>
|
|
</font></tt>
|
|
|
|
</table>
|
|
to use the current standard files. The correct code is<br>
|
|
|
|
<table border=0 cellpadding=0 cellspacing=0><tr height=2><td><tr><td width=20><td>
|
|
|
|
<tt><font size=+1>fd[0] = dup(0, −1);<br>
|
|
fd[1] = dup(1, −1);<br>
|
|
fd[2] = dup(2, −1);<br>
|
|
|
|
<table border=0 cellpadding=0 cellspacing=0><tr height=5><td></table>
|
|
</font></tt>
|
|
|
|
</table>
|
|
<i>Threadspawn</i> is like <i>threadexec</i> but does not replace the current
|
|
thread. It returns the pid of the invoked program on success,
|
|
or –1 on error.
|
|
<table border=0 cellpadding=0 cellspacing=0><tr height=5><td></table>
|
|
|
|
<i>Threadwaitchan</i> returns a channel of pointers to <tt><font size=+1>Waitmsg</font></tt> structures
|
|
(see <a href="../man3/wait.html"><i>wait</i>(3)</a>). When an exec’ed process exits, a pointer to a <tt><font size=+1>Waitmsg</font></tt>
|
|
is sent to this channel. These <tt><font size=+1>Waitmsg</font></tt> structures have been allocated
|
|
with <a href="../man3/malloc.html"><i>malloc</i>(3)</a> and should be freed after use.
|
|
<table border=0 cellpadding=0 cellspacing=0><tr height=5><td></table>
|
|
|
|
A <tt><font size=+1>Channel</font></tt> is a buffered or unbuffered queue for fixed-size messages.
|
|
Procs and threads <i>send</i> messages into the channel and <i>recv</i> messages
|
|
from the channel. If the channel is unbuffered, a <i>send</i> operation
|
|
blocks until the corresponding <i>recv</i> operation occurs and <i>vice
|
|
versa</i>. <i>Chaninit</i> initializes a <tt><font size=+1>Channel</font></tt> for
|
|
messages of size <i>elsize</i> and with a buffer holding <i>nel</i> messages.
|
|
If <i>nel</i> is zero, the channel is unbuffered. <i>Chancreate</i> allocates
|
|
a new channel and initializes it. <i>Chanfree</i> frees a channel that
|
|
is no longer used. <i>Chanfree</i> can be called by either sender or
|
|
receiver after the last item has been sent or received. Freeing
|
|
the
|
|
channel will be delayed if there is a thread blocked on it until
|
|
that thread unblocks (but <i>chanfree</i> returns immediately).
|
|
<table border=0 cellpadding=0 cellspacing=0><tr height=5><td></table>
|
|
|
|
The <tt><font size=+1>name</font></tt> element in the <tt><font size=+1>Channel</font></tt> structure is a description intended
|
|
for use in debugging. <i>Chansetname</i> sets the name.
|
|
<table border=0 cellpadding=0 cellspacing=0><tr height=5><td></table>
|
|
|
|
<i>Send</i> sends the element pointed at by <i>v</i> to the channel <i>c</i>. If <i>v</i>
|
|
is null, zeros are sent. <i>Recv</i> receives an element from <i>c</i> and stores
|
|
it in <i>v</i>. If <i>v</i> is null, the received value is discarded. <i>Send</i> and
|
|
<i>recv</i> return 1 on success, –1 if interrupted. <i>Nbsend</i> and <i>nbrecv</i>
|
|
behave similarly, but return 0 rather than blocking.
|
|
<table border=0 cellpadding=0 cellspacing=0><tr height=5><td></table>
|
|
|
|
<i>Sendp</i>, <i>nbsendp</i>, <i>sendul</i>, and <i>nbsendul</i> send a pointer or an unsigned
|
|
long; the channel must have been initialized with the appropriate
|
|
<i>elsize</i>. <i>Recvp</i>, <i>nbrecvp</i>, <i>recvul</i>, and <i>nbrecvul</i> receive a pointer
|
|
or an unsigned long; they return zero when a zero is received,
|
|
when interrupted, or (for <i>nbrecvp</i> and <i>nbrecvul</i>) when the
|
|
operation would have blocked. To distinguish between these three
|
|
cases, use <i>recv</i> or <i>nbrecv</i>.
|
|
<table border=0 cellpadding=0 cellspacing=0><tr height=5><td></table>
|
|
|
|
<i>Alt</i> can be used to recv from or send to one of a number of channels,
|
|
as directed by an array of <tt><font size=+1>Alt</font></tt> structures, each of which describes
|
|
a potential send or receive operation. In an <tt><font size=+1>Alt</font></tt> structure, <tt><font size=+1>c</font></tt>
|
|
is the channel; <tt><font size=+1>v</font></tt> the value pointer (which may be null); and <tt><font size=+1>op</font></tt>
|
|
the operation: <tt><font size=+1>CHANSND</font></tt> for a send operation,
|
|
<tt><font size=+1>CHANRECV</font></tt> for a recv operation; <tt><font size=+1>CHANNOP</font></tt> for no operation (useful
|
|
when <i>alt</i> is called with a varying set of operations). The array
|
|
of <tt><font size=+1>Alt</font></tt> structures is terminated by an entry with <i>op</i> <tt><font size=+1>CHANEND</font></tt> or
|
|
<tt><font size=+1>CHANNOBLK</font></tt>. If at least one <tt><font size=+1>Alt</font></tt> structure can proceed, one of them
|
|
is chosen at random to be executed. <i>Alt</i> returns the
|
|
index of the chosen structure. If no operations can proceed and
|
|
the list is terminated with <tt><font size=+1>CHANNOBLK</font></tt>, <i>alt</i> returns the index of
|
|
the terminating <tt><font size=+1>CHANNOBLK</font></tt> structure. Otherwise, <i>alt</i> blocks until
|
|
one of the operations can proceed, eventually returning the index
|
|
of the structure executes. <i>Alt</i> returns –1 when
|
|
interrupted. The <tt><font size=+1>tag</font></tt> and <tt><font size=+1>entryno</font></tt> fields in the <tt><font size=+1>Alt</font></tt> structure are
|
|
used internally by <i>alt</i> and need not be initialized. They are not
|
|
used between <i>alt</i> calls.
|
|
<table border=0 cellpadding=0 cellspacing=0><tr height=5><td></table>
|
|
|
|
<i>Chanprint</i> formats its arguments in the manner of <a href="../man3/print.html"><i>print</i>(3)</a> and
|
|
sends the result to the channel <i>c.</i> The string delivered by <i>chanprint</i>
|
|
is allocated with <a href="../man3/malloc.html"><i>malloc</i>(3)</a> and should be freed upon receipt.
|
|
|
|
<table border=0 cellpadding=0 cellspacing=0><tr height=5><td></table>
|
|
|
|
Thread library functions do not return on failure; if errors occur,
|
|
the entire program is aborted.
|
|
<table border=0 cellpadding=0 cellspacing=0><tr height=5><td></table>
|
|
|
|
Threaded programs should use <i>threadnotify</i> in place of <i>atnotify</i>
|
|
(see <a href="../man3/notify.html"><i>notify</i>(3)</a>).
|
|
<table border=0 cellpadding=0 cellspacing=0><tr height=5><td></table>
|
|
|
|
It is safe to use <a href="../man3/sysfatal.html"><i>sysfatal</i>(3)</a> in threaded programs. <i>Sysfatal</i> will
|
|
print the error string and call <i>threadexitsall</i>.
|
|
<table border=0 cellpadding=0 cellspacing=0><tr height=5><td></table>
|
|
|
|
It is not safe to call <i>rfork</i> in a threaded program, except to
|
|
call <tt><font size=+1>rfork(RFNOTEG)</font></tt> from the main proc before any other procs
|
|
have been created. To create new processes, use <i>proccreate</i>.<br>
|
|
|
|
</table>
|
|
<p><font size=+1><b>FILES </b></font><br>
|
|
|
|
<table border=0 cellpadding=0 cellspacing=0><tr height=2><td><tr><td width=20><td>
|
|
|
|
<tt><font size=+1>/usr/local/plan9/acid/thread</font></tt> contains useful <a href="../man1/acid.html"><i>acid</i>(1)</a> functions
|
|
for debugging threaded programs.
|
|
<table border=0 cellpadding=0 cellspacing=0><tr height=5><td></table>
|
|
|
|
<tt><font size=+1>/usr/local/plan9/src/libthread/test</font></tt> contains some example programs.<br>
|
|
|
|
</table>
|
|
<p><font size=+1><b>SOURCE </b></font><br>
|
|
|
|
<table border=0 cellpadding=0 cellspacing=0><tr height=2><td><tr><td width=20><td>
|
|
|
|
<tt><font size=+1>/usr/local/plan9/src/libthread<br>
|
|
</font></tt>
|
|
</table>
|
|
<p><font size=+1><b>SEE ALSO </b></font><br>
|
|
|
|
<table border=0 cellpadding=0 cellspacing=0><tr height=2><td><tr><td width=20><td>
|
|
|
|
<a href="../man3/intro.html"><i>intro</i>(3)</a>, <a href="../man3/ioproc.html"><i>ioproc</i>(3)</a><br>
|
|
|
|
</table>
|
|
<p><font size=+1><b>BUGS </b></font><br>
|
|
|
|
<table border=0 cellpadding=0 cellspacing=0><tr height=2><td><tr><td width=20><td>
|
|
|
|
To avoid name conflicts, <i>alt</i>, <i>nbrecv</i>, <i>nbrecvp</i>, <i>nbrecvul</i>, <i>nbsend</i>,
|
|
<i>nbsendp</i>, <i>nbsendul</i>, <i>recv</i>, <i>recvp</i>, <i>recvul</i>, <i>send</i>, <i>sendp</i>, and <i>sendul</i>
|
|
are defined as macros that expand to <i>chanalt</i>, <i>channbrecv</i>, and
|
|
so on. <i>Yield</i> is defined as a macro that expands to <i>threadyield</i>.
|
|
See <a href="../man3/intro.html"><i>intro</i>(3)</a>.
|
|
<table border=0 cellpadding=0 cellspacing=0><tr height=5><td></table>
|
|
|
|
The implementation of <i>threadnotify</i> may not be correct.<br>
|
|
|
|
</table>
|
|
|
|
<td width=20>
|
|
<tr height=20><td>
|
|
</table>
|
|
<!-- TRAILER -->
|
|
<table border=0 cellpadding=0 cellspacing=0 width=100%>
|
|
<tr height=15><td width=10><td><td width=10>
|
|
<tr><td><td>
|
|
<center>
|
|
<a href="../../"><img src="../../dist/spaceglenda100.png" alt="Space Glenda" border=1></a>
|
|
</center>
|
|
</table>
|
|
<!-- TRAILER -->
|
|
</body></html>
|