Skip site navigation (1)Skip section navigation (2)

FreeBSD Manual Pages


home | help
THREAD(3)		   Library Functions Manual		     THREAD(3)

       alt, chancreate,	chanfree, chanprint, chansetname, mainstacksize, proc-
       create, 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, threadpin,  threadunpin,
       threadsetgrp, threadsetname, threadsetstate, threadspawn, threadspawnd,
       threadspawnl, threadwaitchan, yield - thread and	proc management

       #include	<u.h>
       #include	<libc.h>
       #include	<thread.h>

       #define CHANEND	   0
       #define CHANSND	   1
       #define CHANRCV	   2
       #define CHANNOP	   3
       #define CHANNOBLK   4

       typedef struct Alt Alt;
       struct Alt {
	   Channel *c;
	   void	   *v;
	   int	   op;
	   Channel **tag;
	   int	   entryno;
	   char	   *name;

       void	threadmain(int argc, char *argv[])
       int	mainstacksize
       int	proccreate(void	(*fn)(void*), void *arg, uint stacksize)
       int	threadcreate(void (*fn)(void*),	void *arg, uint	stacksize)
       void	threadexits(char *status)
       void	threadexitsall(char *status)
       void	yield(void)
       int	threadpin(void)
       int	threadunpin(void)

       int	threadid(void)
       int	threadgrp(void)
       int	threadsetgrp(int group)
       int	threadpid(int id)

       int	threadint(int id)
       int	threadintgrp(int group)
       int	threadkill(int id)
       int	threadkillgrp(int group)

       void	threadsetname(char *name)
       char*	threadgetname(void)

       void**	threaddata(void)
       void**	procdata(void)

       Channel*	chancreate(int elsize, int nel)
       void	chanfree(Channel *c)

       int	alt(Alt	*alts)
       int	recv(Channel *c, void *v)
       void*	recvp(Channel *c)
       ulong	recvul(Channel *c)
       int	nbrecv(Channel *c, void	*v)
       void*	nbrecvp(Channel	*c)
       ulong	nbrecvul(Channel *c)
       int	send(Channel *c, void *v)
       int	sendp(Channel *c, void *v)
       int	sendul(Channel *c, ulong v)
       int	nbsend(Channel *c, void	*v)
       int	nbsendp(Channel	*c, void *v)
       int	nbsendul(Channel *c, ulong v)
       int	chanprint(Channel *c, char *fmt, ...)

       int	threadspawnl(int fd[3],	char *file, ...)
       int	threadspawn(int	fd[3], char *file, char	*args[])
       int	threadspawnd(int fd[3],	char *file, char *args[], char *dir)
       int	threadexecl(Channel *cpid, int fd[3], char *file, ...)
       int	threadexec(Channel *cpid, int fd[3], char *file, char *args[])
       Channel*	threadwaitchan(void)

       int	threadnotify(int (*f)(void*, char*), int in)

       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 thread-
       main.   The thread library provides a main function that	sets up	a proc
       with a single thread executing threadmain on a stack of size mainstack-
       size (default eight kilobytes).	To set mainstacksize, declare a	global
       variable	initialized to the desired value (e.g.,	 int  mainstacksize  =
       1024).  When using the pthread library, mainstacksize is	ignored, as is
       the stack size argument to proccreate: the first	thread	in  each  proc
       runs on the native system stack.

       Threadcreate  creates  a	 new  thread  in the calling proc, returning a
       unique integer identifying the thread; the thread executes fn(arg) on a
       stack of	size stacksize.	 Thread	stacks are allocated in	shared memory,
       making it valid to pass pointers	to stack variables between threads and
       procs.	Proccreate  creates a new proc,	and inside that	proc creates a
       single thread as	threadcreate 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,  arg
       should  not  point to data on the stack of a function that could	return
       before the new process is scheduled.

       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.

       When  the  last thread in threadmain's proc exits, the program will ap-
       pear to its parent to have exited.  The remaining procs will still  run
       together, but as	a background program.

       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	yield, proccreate, threadexec, threadexecl,  threadex-
       its,  threadspawn, threadspawnd,	threadspawnl, alt, send, and recv (and
       the calls related to send and recv--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 qlocks	(see or	channel	communication.
       System calls such as block the entire proc; all threads in a proc block
       until the system	call finishes.

       Threadpin  disables  scheduling	inside	a  proc, `pinning' the current
       thread as the only runnable one in the current proc.  Threadunpin reen-
       ables  scheduling,  allowing other procs	to run once the	current	thread
       relinquishes the	processor.  Threadpin  and  threadunpin	 can  lead  to
       deadlock.   Used	 carefully,  they  can	make library routines that use
       qlocks appear atomic relative to	the current proc, like a system	call.

       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 re-
       linquishes the processor.

       Primarily for debugging,	threads	can have string	names associated  with
       them.   Threadgetname  returns the current thread's name; threadsetname
       sets it.	 The pointer returned by threadgetname is only valid until the
       next call to threadsetname.

       Also  for  debugging, threads have a string state associated with them.
       Threadsetstate sets the state  string.	There  is  no  threadgetstate;
       since  the  thread  scheduler resets the	state to Running every time it
       runs the	thread,	it is only useful for debuggers	to inspect the state.

       Threaddata returns a pointer to a per-thread pointer that may be	 modi-
       fied  by	threaded programs for per-thread storage.  Similarly, procdata
       returns a pointer to a per-proc pointer.

       Threadexecl and threadexec are threaded analogues  of  exec  and	 execl
       (see  on	success, they replace the calling thread and invoke the	exter-
       nal program, never returning.  (Unlike on Plan 9,  the  calling	thread
       need  not  be  the only thread in its proc--the other threads will con-
       tinue executing.)  On error, they return	-1.  If	cpid is	not null,  the
       pid  of the invoked program will	be sent	along cpid (using sendul) once
       the program has been started, or	-1 will	be sent	if  an	error  occurs.
       Threadexec  and threadexecl will	not access their arguments after send-
       ing a result along cpid.	 Thus, programs	that malloc the	argv passed to
       threadexec  can	safely	free  it  once they have received the cpid re-

       Threadexecl and threadexec will duplicate (see the three	file  descrip-
       tors in fd onto standard	input, output, and error for the external pro-
       gram and	then close them	in the calling thread.	Beware	of  code  that

	      fd[0] = 0;
	      fd[1] = 1;
	      fd[2] = 2;

       to use the current standard files.  The correct code is

	      fd[0] = dup(0, -1);
	      fd[1] = dup(1, -1);
	      fd[2] = dup(2, -1);

       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.  Threadspawnd is like threadspawn
       but takes as its	final argument the directory in	which to run  the  in-
       voked  program.	 The  child will attempt to change into	that directory
       before running the program, but it is  only  best  effort:  failure  to
       change into the directory does not stop the running of the program.

       Threadwaitchan returns a	channel	of pointers to Waitmsg structures (see
       When an exec'ed process exits, a	pointer	to a Waitmsg is	sent  to  this
       channel.	  These	Waitmsg	structures have	been allocated with and	should
       be freed	after use.

       A Channel is a buffered or unbuffered queue  for	 fixed-size  messages.
       Procs and threads send messages into the	channel	and recv messages from
       the channel.  If	the channel is unbuffered, a send operation blocks un-
       til the corresponding recv operation occurs and vice versa.  Chancreate
       allocates a new channel for messages of size elsize and with  a	buffer
       holding	nel  messages.	 If  nel  is  zero, the	channel	is unbuffered.
       Chanfree	frees a	channel	that is	 no  longer  used.   Chanfree  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 chanfree returns immedi-

       The name	element	in the Channel structure is a description intended for
       use in debugging.  Chansetname sets the name.

       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  el-
       size.  Recvp, nbrecvp, recvul, and nbrecvul receive a pointer or	an un-
       signed long; they return	zero when a  zero  is  received,  when	inter-
       rupted,	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 po-
       tential send or receive operation.  In an Alt structure,	c is the chan-
       nel;  v	the  value  pointer (which may be null); and op	the operation:
       CHANSND for a send operation, CHANRECV for a  recv  operation;  CHANNOP
       for no operation	(useful	when alt is called with	a varying set of oper-
       ations).	 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 and sends the	result
       to the channel c.  The string delivered by chanprint is allocated  with
       and should be freed upon	receipt.

       Thread library functions	do not return on failure; if errors occur, the
       entire program is aborted.

       Threaded	programs should	use threadnotify in place of atnotify (see

       It is safe to use in threaded programs.	Sysfatal will print the	 error
       string and call threadexitsall.

       It  is  not  safe  to  call rfork in a threaded program,	except to call
       rfork(RFNOTEG) from the main proc before	any other procs	have been cre-
       ated.  To create	new processes, use proccreate.

       /acid/thread contains useful functions for debugging threaded programs.

       /src/libthread/test contains some example programs.


       To  avoid  name	conflicts, alt,	nbrecv,	nbrecvp, nbrecvul, nbsend, nb-
       sendp, nbsendul,	recv, recvp, recvul, send, sendp, and sendul  are  de-
       fined  as  macros that expand to	chanalt, channbrecv, and so on.	 Yield
       is defined as a macro that expands to threadyield.  See

       Threadint, threadintgrp,	threadkill, threadkillgrp  and	threadpid  are

       The implementation of threadnotify may not be correct.

       There  appears  to  be  a  race	in  the	 Linux	NPTL implementation of
       pthread_exit .  Call threadexitsall rather than coordinating a simulta-
       neous threadexits among many threads.



Want to link to this manual page? Use this URL:

home | help