1thr_create(3C)           Standard C Library Functions           thr_create(3C)
2
3
4

NAME

6       thr_create - create a thread
7

SYNOPSIS

9       cc -mt [ flag... ] file...[ library... ]
10       #include <thread.h>
11
12       int thr_create(void *stack_base, size_t stack_size,
13            void *(*start_func) (void*), void *arg, long flags,
14            thread_t *new_thread_ID);
15
16

DESCRIPTION

18       Thread  creation  adds  a new thread of control to the current process.
19       The procedure main() is a single thread of control.  Each  thread  exe‐
20       cutes  concurrently  with  all other threads within the calling process
21       and with other  threads from other active processes.
22
23
24       Although a newly created thread shares all  of  the  calling  process's
25       global  data  with the other threads in the process, it has its own set
26       of attributes and private execution stack.  The new thread inherits the
27       calling  thread's  signal mask and scheduling priority. Pending signals
28       for a new thread are not inherited and will be empty.
29
30
31       The call to create a thread takes the address of a user-defined   func‐
32       tion,  specified  by start_func, as one of its arguments. This function
33       is the complete execution routine for the new thread.
34
35
36       The lifetime of  a  thread  begins  with  the  successful  return  from
37       thr_create(), which calls start_func() and ends with one of the follow‐
38       ing:
39
40           o      the normal completion of start_func(),
41
42           o      an explicit call to thr_exit(3C), or
43
44           o      the conclusion of the calling process (see exit(2)).
45
46
47       The new thread performs by calling the function defined  by  start_func
48       with  only  one  argument,  arg.  If more than one argument needs to be
49       passed to start_func, the arguments can be packed into a structure, the
50       address of which can be passed to arg.
51
52
53       If  start_func  returns, the thread terminates with the exit status set
54       to the start_func return value (see thr_exit(3C)).
55
56
57       When the thread from which main() originated returns, the effect is the
58       same  as if an implicit call to exit() were made using the return value
59       of main() as the exit status. This behavior differs from  a  start_func
60       return.  If main()  calls thr_exit(3C), only the main thread exits, not
61       the entire process.
62
63
64       If the thread creation  fails, a new thread is not created and the con‐
65       tents  of  the location referenced by the pointer to the new thread are
66       undefined.
67
68
69       The flags argument specifies which attributes are  modifiable  for  the
70       created  thread. The value in flags is determined by the bitwise inclu‐
71       sive-OR of the following:
72
73       THR_BOUND         This flag is obsolete and is maintained for  compati‐
74                         bility.
75
76
77       THR_DETACHED      This  flag  affects  the detachstate attribute of the
78                         thread. The new thread is created detached. The  exit
79                         status  of  a  detached  thread  is not accessible to
80                         other threads. Its thread ID and other resources  may
81                         be   re-used   as  soon  as  the  thread  terminates.
82                         thr_join(3C) will not wait for a detached thread.
83
84
85       THR_NEW_LWP       This flag is obsolete and is maintained for  compati‐
86                         bility.
87
88
89       THR_SUSPENDED     This  flag  affects  the  suspended  attribute of the
90                         thread. The new thread is created suspended and  will
91                         not   execute  start_func  until  it  is  started  by
92                         thr_continue().
93
94
95       THR_DAEMON        This flag affects the daemon attribute of the thread.
96                         In  addition  to  being  created detached (THR_DAEMON
97                         implies THR_DETACHED), the thread is marked as a dae‐
98                         mon.  Daemon  threads  do not interfere with the exit
99                         conditions for a process. A  process  will  terminate
100                         when  the last non-daemon thread exits or the process
101                         calls exit(2). Also, a  thread  that  is  waiting  in
102                         thr_join(3C)  for any thread to terminate will return
103                         EDEADLK when all remaining threads in the process are
104                         either  daemon  threads  or  other threads waiting in
105                         thr_join().  Daemon  threads  are  most   useful   in
106                         libraries that want to use threads.
107
108
109
110       Default thread creation:
111
112         thread_t tid;
113         void *start_func(void *), *arg;
114         thr_create(NULL, 0, start_func, arg, 0, &tid);
115
116
117
118       Create a detached thread whose thread ID we do not care about:
119
120         thr_create(NULL, 0, start_func, arg, THR_DETACHED, NULL);
121
122
123
124       If  stack_base  is not NULL, the new thread uses the stack beginning at
125       the address specified  by  stack_base  and  continuing  for  stack_size
126       bytes, where stack_size must be greater than or equal to THR_MIN_STACK.
127       If stack_base is NULL, thr_create()  allocates  a  stack  for  the  new
128       thread  with  at  least stack_size bytes. If stack_size is 0, a default
129       size is used. If stack_size is not 0, it must be greater than or  equal
130       to THR_MIN_STACK. See  NOTES.
131
132
133       When   new_thread_ID  is not NULL, it points to a location where the ID
134       of the new thread is stored if thr_create() is successful.  The  ID  is
135       only valid within the calling process.
136

RETURN VALUES

138       If  successful,  the  thr_create()  function  returns 0. Otherwise,  an
139       error value is returned to indicate the error.
140

ERRORS

142       EAGAIN     A resource control limit on the total number of threads in a
143                  process,  task,  project,  or zone has been exceeded or some
144                  system resource has been exceeded.
145
146
147       EINVAL     The stack_base argument is not NULL and stack_size  is  less
148                  than  THR_MIN_STACK,  or the stack_base argument is NULL and
149                  stack_size is not 0 and is less than THR_MIN_STACK.
150
151
152       ENOMEM     The system cannot allocate stack for the thread.
153
154
155
156       The thr_create() function may use mmap()  to   allocate  thread  stacks
157       from  MAP_PRIVATE,  MAP_NORESERVE,  and  MAP_ANON  memory  mappings  if
158       stack_base is NULL, and consequently may return upon failure the  rele‐
159       vant  error  values returned by mmap(). See the mmap(2) manual page for
160       these error values.
161

EXAMPLES

163       The following is an example of concurrency with  multithreading.  Since
164       POSIX threads and Solaris threads are fully compatible  even within the
165       same process, this example uses pthread_create() if you  execute  a.out
166       0, or thr_create() if you execute a.out 1.
167
168
169       Five  threads  are created that simultaneously perform a time-consuming
170       function, sleep(10). If the execution of this  process  is  timed,  the
171       results will show  that all five individual calls to sleep for ten-sec‐
172       onds completed  in about ten seconds, even on a uniprocessor. If a sin‐
173       gle-threaded  process  calls  sleep(10)  five times, the execution time
174       will be about 50-seconds.
175
176
177       The command-line to time this process is:
178
179
180       /usr/bin/time a.out 0 (for POSIX threading)
181
182
183       or
184
185
186       /usr/bin/time a.out 1 (for Solaris threading)
187
188       Example 1 An example of concurrency with multithreading.
189
190         #define _REENTRANT    /* basic 3-lines for threads */
191         #include <pthread.h>
192         #include <thread.h>
193         #define NUM_THREADS 5
194         #define SLEEP_TIME 10
195
196         void *sleeping(void *);   /* thread routine */
197         int i;
198         thread_t tid[NUM_THREADS];      /* array of thread IDs */
199
200         int
201         main(int argc, char *argv[])
202         {
203             if (argc == 1)  {
204                 printf("use 0 as arg1 to use pthread_create()\n");
205                 printf("or use 1 as arg1 to use thr_create()\n");
206                 return (1);
207             }
208
209             switch (*argv[1])  {
210             case '0':  /* POSIX */
211                 for ( i = 0; i < NUM_THREADS; i++)
212                         pthread_create(&tid[i], NULL, sleeping,
213                             (void *)SLEEP_TIME);
214                 for ( i = 0; i < NUM_THREADS; i++)
215                             pthread_join(tid[i], NULL);
216                 break;
217
218             case '1':  /* Solaris */
219                 for ( i = 0; i < NUM_THREADS; i++)
220                     thr_create(NULL, 0, sleeping, (void *)SLEEP_TIME, 0,
221                         &tid[i]);
222                 while (thr_join(0, NULL, NULL) == 0)
223                         continue;
224                 break;
225             }  /* switch */
226             printf("main() reporting that all %d threads have
227                 terminated\n", i);
228             return (0);
229         }  /* main */
230
231         void *
232         sleeping(void *arg)
233         {
234             int sleep_time = (int)arg;
235             printf("thread %d sleeping %d seconds ...\n", thr_self(),
236                 sleep_time);
237             sleep(sleep_time);
238             printf("\nthread %d awakening\n", thr_self());
239             return (NULL);
240         }
241
242
243
244       Had main() not waited for the completion of the  other  threads  (using
245       pthread_join(3C)  or  thr_join(3C)), it would have continued to process
246       concurrently until it reached the end of its  routine  and  the  entire
247       process would have exited prematurely (see exit(2)).
248
249
250       Example 2 Creating a default thread with a new signal mask.
251
252
253       The  following example demonstrates how to create a default thread with
254       a new signal mask. The new_mask argument is assumed  to  have  a  value
255       different  from  the  creator's signal mask (orig_mask).   The new_mask
256       argument is set to block all signals except for SIGINT.  The  creator's
257       signal  mask  is  changed  so  that the new thread inherits a different
258       mask, and is restored to its original value after thr_create() returns.
259
260
261
262       This example assumes that SIGINT is also unmasked in the creator.    If
263       it  is  masked by the creator, then unmasking the signal opens the cre‐
264       ator to this signal.   The other alternative is to have the new  thread
265       set its own signal mask in its start routine.
266
267
268         thread_t tid;
269         sigset_t new_mask, orig_mask;
270         int error;
271
272         (void)sigfillset(&new_mask);
273         (void)sigdelset(&new_mask, SIGINT);
274         (void)thr_sigsetmask(SIG_SETMASK, &new_mask, &orig_mask);
275         error = thr_create(NULL, 0, do_func, NULL, 0, &tid);
276         (void)thr_sigsetmask(SIG_SETMASK, &orig_mask, NULL);
277
278

ATTRIBUTES

280       See attributes(5) for descriptions of the following attributes:
281
282
283
284
285       ┌─────────────────────────────┬─────────────────────────────┐
286       │      ATTRIBUTE TYPE         │      ATTRIBUTE VALUE        │
287       ├─────────────────────────────┼─────────────────────────────┤
288       │MT-Level                     │MT-Safe                      │
289       └─────────────────────────────┴─────────────────────────────┘
290

SEE ALSO

292       exit(2),  getrlimit(2),  mmap(2),  exit(3C),  sleep(3C),  thr_exit(3C),
293       thr_join(3C),   thr_min_stack(3C),   thr_setconcurrency(3C),   thr_sus‐
294       pend(3C), attributes(5), standards(5), threads(5)
295

NOTES

297       Since  multithreaded-application  threads execute independently of each
298       other, their relative behavior is unpredictable. It is therefore possi‐
299       ble  for  the  thread executing main() to finish before all other user-
300       application threads.
301
302
303       Using thr_join(3C) in the following syntax,
304
305         while (thr_join(0, NULL, NULL) == 0)
306             continue;
307
308
309
310       will cause the invoking thread (which may be main()) to  wait  for  the
311       termination of all non-daemon threads, excluding threads that are them‐
312       selves waiting in thr_join(); however, the second and  third  arguments
313       to thr_join() need not necessarily be NULL.
314
315
316       A  thread  has  not terminated until thr_exit() has finished.  The only
317       way to determine this is  by  thr_join().  When  thr_join()  returns  a
318       departed  thread,  it  means  that  this  thread has terminated and its
319       resources are reclaimable. For instance, if a user specified a stack to
320       thr_create(),  this  stack  can only be reclaimed after  thr_join() has
321       reported this thread as a departed thread.    It  is  not  possible  to
322       determine  when  a  detached thread has terminated.   A detached thread
323       disappears without leaving a trace.
324
325
326       Typically, thread stacks allocated by thr_create() begin on page bound‐
327       aries  and  any  specified  (a red-zone) size is rounded up to the next
328       page boundary. A page with no access permission is appended to the  top
329       of the stack so that most stack overflows will result in a SIGSEGV sig‐
330       nal being sent to the offending thread. Thread stacks allocated by  the
331       caller are used as is.
332
333
334       Using  a  default  stack  size for the new thread, instead of passing a
335       user-specified stack size, results in much better thr_create()  perfor‐
336       mance.  The  default  stack  size for a user-thread  is 1 megabyte in a
337       32-bit process and 2 megabyte in a 64-bit process.
338
339
340       A  user-specified  stack  size  must  be  greater  than  or  equal   to
341       THR_MIN_STACK. A minimum stack size may not accommodate the stack frame
342       for  the user thread function start_func. If a stack size is specified,
343       it  must  accommodate start_func requirements and the functions that it
344       may call in turn,  in addition to the minimum requirement.
345
346
347       It is usually very difficult to determine the runtime  stack   require‐
348       ments  for  a thread. THR_MIN_STACK specifies how much stack storage is
349       required to execute a trivial start_func. The  total  runtime  require‐
350       ments  for  stack  storage  are dependent on the storage required to do
351       runtime linking, the amount of storage  required  by  library  runtimes
352       (like  printf()) that your thread calls. Since these storage parameters
353       are not known before the program  runs,  it  is  best  to  use  default
354       stacks.  If  you know your runtime requirements or decide to use stacks
355       that are larger than the default, then it makes sense to  specify  your
356       own stacks.
357
358
359
360SunOS 5.11                        16 Mar 2009                   thr_create(3C)
Impressum