NAME
alt, chanclose, chancreate, chanfree, chaninit, chanclosing, chanprint,
mainstacksize, proccreate, procdata, procexec, procexecl, procrfork,
recv, recvp, recvul, send, sendp, sendul, nbrecv, nbrecvp, nbrecvul,
nbsend, nbsendp, nbsendul, threadcreate, threaddata, threadexits,
threadexitsall, threadgetgrp, threadgetname,
threadint, threadintgrp, threadkill, threadkillgrp, threadmain,
threadnotify, threadid, threadpid, threadsetgrp, threadsetname,
threadspawn, threadspawnl, threadwaitchan, yield – thread and proc
management |
SYNOPSIS
#include <u.h> #include <libc.h> #include <thread.h> typedef enum {
typedef struct Alt Alt; struct Alt {
void threadmain(int argc, char *argv[]) |
DESCRIPTION
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 channels and shared variables.
A proc is a Plan 9 process that contains one or more cooperatively–scheduled
threads. Programs using threads must replace main by threadmain.
The thread library provides a main function that sets up a proc
with a single thread executing threadmain on a stack of size mainstacksize
(default eight kilobytes). To set
mainstacksize, declare a global variable initialized to the desired
value (e.g., int mainstacksize = 1024). Creation
Threadexits terminates the calling thread. If the thread is the
last in its proc, threadexits also terminates the proc, using
status as the exit status. Threadexitsall terminates all procs
in the program, using status as the exit status. Scheduling 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. Threadid 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. Threadgrp returns the group id for the current thread; threadsetgrp sets it. Threadpid returns the pid of the Plan 9 process containing the thread identified by id, or –1 if no such thread is found.
Threadint interrupts a thread that is blocked in a channel operation
or system call. Threadintgrp interrupts all threads with the given
group id. Threadkill 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. Threadkillgrp kills all threads with the given
group id. Note that threadkill and threadkillgrp will not terminate
a thread that never relinquishes the processor. Names and per–thread data
Threaddata returns a pointer to a per–thread pointer that may be
modified by threaded programs for per–thread storage. Similarly,
procdata returns a pointer to a per–proc pointer. Executing new programs Threadspawnl and threadspawn are like threadexecl and threadexec but do not replace the current thread. They return the pid of the invoked program on success, or –1 on error.
Threadwaitchan returns a channel of pointers to Waitmsg structures
(see wait(2)). When an exec'ed process exits, a pointer to a Waitmsg
is sent to this channel. These Waitmsg structures have been allocated
with malloc(2) and should be freed after use. Channels Send sends the element pointed at by v to the channel c. If v is null, zeros are sent. Recv receives an element from c and stores it in v. If v is null, the received value is discarded. Send and recv return 1 on success, –1 if interrupted. Nbsend and nbrecv behave similarly, but return 0 rather than blocking. Sendp, nbsendp, sendul, and nbsendul send a pointer or an unsigned long; the channel must have been initialized with the appropriate elsize. Recvp, nbrecvp, recvul, and nbrecvul receive a pointer or an unsigned long; they return zero when a zero is received, when interrupted, or (for nbrecvp and nbrecvul) when the operation would have blocked. To distinguish between these three cases, use recv or nbrecv. Alt can be used to recv from or send to one of a number of channels, as directed by an array of Alt structures, each of which describes a potential send or receive operation. In an Alt structure, c is the channel; v the value pointer (which may be null); and op the operation: CHANSND for a send operation, CHANRCV for a recv operation; CHANNOP for no operation (useful when alt is called with a varying set of operations). The array of Alt structures is terminated by an entry with op CHANEND or CHANNOBLK. If at least one Alt structure can proceed, one of them is chosen at random to be executed. Alt returns the index of the chosen structure. If no operations can proceed and the list is terminated with CHANNOBLK, alt returns the index of the terminating CHANNOBLK structure. Otherwise, alt blocks until one of the operations can proceed, eventually returning the index of the structure executes. Alt returns –1 when interrupted. The tag and entryno fields in the Alt structure are used internally by alt and need not be initialized. They are not used between alt calls. Chanprint formats its arguments in the manner of print(2) and sends the result to the channel c. The string delivered by chanprint is allocated with malloc(2) and should be freed upon receipt.
Chanclose prevents further elements being sent to the channel
c. After closing a channel, send and recv never block. Send always
returns –1. Recv returns –1 if the channel is empty. Alt may choose
a CHANSND or CHANRCV that failed because the channel was closed.
In this case, the err field of the Alt entry points
to an error string stating that the channel was closed and the
operation was completed with failure. If all entries have been
selected and failed because they were closed, alt returns –1. Errors, notes and resources Chanclosing returns –1 if no one called closed on the channel, and otherwise the number of elements still in the channel. Threaded programs should use threadnotify in place of atnotify (see notify(2)). It is safe to use sysfatal (see perror(2)) in threaded programs. Sysfatal will print the error string and call threadexitsall.
It is safe to use rfork (see fork(2)) to manage the namespace,
file descriptors, note group, and environment of a single process.
That is, it is safe to call rfork with the flags RFNAMEG, RFFDG,
RFCFDG, RFNOTEG, RFENVG, and RFCENVG. (To create new processes,
use proccreate and procrfork.) As mentioned
above, the thread library depends on all procs being in the same
rendezvous group; do not change the rendezvous group with rfork. |
FILES
/sys/lib/acid/thread useful acid(1) functions for debugging threaded
programs. /sys/src/libthread/example.c
|
SOURCE
/sys/src/libthread |
SEE ALSO
intro(2), ioproc(2), lock(2) |