1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
|
<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>
|