| .\" Copyright (c) 2008 Linux Foundation, written by Michael Kerrisk |
| .\" <mtk.manpages@gmail.com> |
| .\" |
| .\" %%%LICENSE_START(VERBATIM) |
| .\" Permission is granted to make and distribute verbatim copies of this |
| .\" manual provided the copyright notice and this permission notice are |
| .\" preserved on all copies. |
| .\" |
| .\" Permission is granted to copy and distribute modified versions of this |
| .\" manual under the conditions for verbatim copying, provided that the |
| .\" entire resulting derived work is distributed under the terms of a |
| .\" permission notice identical to this one. |
| .\" |
| .\" Since the Linux kernel and libraries are constantly changing, this |
| .\" manual page may be incorrect or out-of-date. The author(s) assume no |
| .\" responsibility for errors or omissions, or for damages resulting from |
| .\" the use of the information contained herein. The author(s) may not |
| .\" have taken the same level of care in the production of this manual, |
| .\" which is licensed free of charge, as they might when working |
| .\" professionally. |
| .\" |
| .\" Formatted or processed versions of this manual, if unaccompanied by |
| .\" the source, must acknowledge the copyright and authors of this work. |
| .\" %%%LICENSE_END |
| .\" |
| .TH PTHREAD_CREATE 3 2021-03-22 "Linux" "Linux Programmer's Manual" |
| .SH NAME |
| pthread_create \- create a new thread |
| .SH SYNOPSIS |
| .nf |
| .B #include <pthread.h> |
| .PP |
| .BI "int pthread_create(pthread_t *restrict " thread , |
| .BI " const pthread_attr_t *restrict " attr , |
| .BI " void *(*" start_routine ")(void *)," |
| .BI " void *restrict " arg ); |
| .fi |
| .PP |
| Compile and link with \fI\-pthread\fP. |
| .SH DESCRIPTION |
| The |
| .BR pthread_create () |
| function starts a new thread in the calling process. |
| The new thread starts execution by invoking |
| .IR start_routine (); |
| .IR arg |
| is passed as the sole argument of |
| .IR start_routine (). |
| .PP |
| The new thread terminates in one of the following ways: |
| .IP * 2 |
| It calls |
| .BR pthread_exit (3), |
| specifying an exit status value that is available to another thread |
| in the same process that calls |
| .BR pthread_join (3). |
| .IP * |
| It returns from |
| .IR start_routine (). |
| This is equivalent to calling |
| .BR pthread_exit (3) |
| with the value supplied in the |
| .I return |
| statement. |
| .IP * |
| It is canceled (see |
| .BR pthread_cancel (3)). |
| .IP * |
| Any of the threads in the process calls |
| .BR exit (3), |
| or the main thread performs a return from |
| .IR main (). |
| This causes the termination of all threads in the process. |
| .PP |
| The |
| .I attr |
| argument points to a |
| .I pthread_attr_t |
| structure whose contents are used at thread creation time to |
| determine attributes for the new thread; |
| this structure is initialized using |
| .BR pthread_attr_init (3) |
| and related functions. |
| If |
| .I attr |
| is NULL, |
| then the thread is created with default attributes. |
| .PP |
| Before returning, a successful call to |
| .BR pthread_create () |
| stores the ID of the new thread in the buffer pointed to by |
| .IR thread ; |
| this identifier is used to refer to the thread |
| in subsequent calls to other pthreads functions. |
| .PP |
| The new thread inherits a copy of the creating thread's signal mask |
| .RB ( pthread_sigmask (3)). |
| The set of pending signals for the new thread is empty |
| .RB ( sigpending (2)). |
| The new thread does not inherit the creating thread's |
| alternate signal stack |
| .RB ( sigaltstack (2)). |
| .PP |
| The new thread inherits the calling thread's floating-point environment |
| .RB ( fenv (3)). |
| .PP |
| The initial value of the new thread's CPU-time clock is 0 |
| (see |
| .BR pthread_getcpuclockid (3)). |
| .\" CLOCK_THREAD_CPUTIME_ID in clock_gettime(2) |
| .SS Linux-specific details |
| The new thread inherits copies of the calling thread's capability sets |
| (see |
| .BR capabilities (7)) |
| and CPU affinity mask (see |
| .BR sched_setaffinity (2)). |
| .SH RETURN VALUE |
| On success, |
| .BR pthread_create () |
| returns 0; |
| on error, it returns an error number, and the contents of |
| .IR *thread |
| are undefined. |
| .SH ERRORS |
| .TP |
| .B EAGAIN |
| Insufficient resources to create another thread. |
| .TP |
| .B EAGAIN |
| .\" NOTE! The following should match the description in fork(2) |
| A system-imposed limit on the number of threads was encountered. |
| There are a number of limits that may trigger this error: the |
| .BR RLIMIT_NPROC |
| soft resource limit (set via |
| .BR setrlimit (2)), |
| which limits the number of processes and threads for a real user ID, |
| was reached; |
| the kernel's system-wide limit on the number of processes and threads, |
| .IR /proc/sys/kernel/threads\-max , |
| was reached (see |
| .BR proc (5)); |
| or the maximum number of PIDs, |
| .IR /proc/sys/kernel/pid_max , |
| was reached (see |
| .BR proc (5)). |
| .TP |
| .B EINVAL |
| Invalid settings in |
| .IR attr . |
| .TP |
| .\" FIXME . Test the following |
| .B EPERM |
| No permission to set the scheduling policy and parameters specified in |
| .IR attr . |
| .SH ATTRIBUTES |
| For an explanation of the terms used in this section, see |
| .BR attributes (7). |
| .ad l |
| .nh |
| .TS |
| allbox; |
| lbx lb lb |
| l l l. |
| Interface Attribute Value |
| T{ |
| .BR pthread_create () |
| T} Thread safety MT-Safe |
| .TE |
| .hy |
| .ad |
| .sp 1 |
| .SH CONFORMING TO |
| POSIX.1-2001, POSIX.1-2008. |
| .SH NOTES |
| See |
| .BR pthread_self (3) |
| for further information on the thread ID returned in |
| .IR *thread |
| by |
| .BR pthread_create (). |
| Unless real-time scheduling policies are being employed, |
| after a call to |
| .BR pthread_create (), |
| it is indeterminate which thread\(emthe caller or the new thread\(emwill |
| next execute. |
| .PP |
| A thread may either be |
| .I joinable |
| or |
| .IR detached . |
| If a thread is joinable, then another thread can call |
| .BR pthread_join (3) |
| to wait for the thread to terminate and fetch its exit status. |
| Only when a terminated joinable thread has been joined are |
| the last of its resources released back to the system. |
| When a detached thread terminates, |
| its resources are automatically released back to the system: |
| it is not possible to join with the thread in order to obtain |
| its exit status. |
| Making a thread detached is useful for some types of daemon threads |
| whose exit status the application does not need to care about. |
| By default, a new thread is created in a joinable state, unless |
| .I attr |
| was set to create the thread in a detached state (using |
| .BR pthread_attr_setdetachstate (3)). |
| .PP |
| Under the NPTL threading implementation, if the |
| .BR RLIMIT_STACK |
| soft resource limit |
| .IR "at the time the program started" |
| has any value other than "unlimited", |
| then it determines the default stack size of new threads. |
| Using |
| .BR pthread_attr_setstacksize (3), |
| the stack size attribute can be explicitly set in the |
| .I attr |
| argument used to create a thread, |
| in order to obtain a stack size other than the default. |
| If the |
| .BR RLIMIT_STACK |
| resource limit is set to "unlimited", |
| a per-architecture value is used for the stack size. |
| Here is the value for a few architectures: |
| .RS |
| .TS |
| allbox; |
| lb lb |
| l r. |
| Architecture Default stack size |
| i386 2 MB |
| IA-64 32 MB |
| PowerPC 4 MB |
| S/390 2 MB |
| Sparc-32 2 MB |
| Sparc-64 4 MB |
| x86_64 2 MB |
| .TE |
| .RE |
| .SH BUGS |
| In the obsolete LinuxThreads implementation, |
| each of the threads in a process has a different process ID. |
| This is in violation of the POSIX threads specification, |
| and is the source of many other nonconformances to the standard; see |
| .BR pthreads (7). |
| .SH EXAMPLES |
| The program below demonstrates the use of |
| .BR pthread_create (), |
| as well as a number of other functions in the pthreads API. |
| .PP |
| In the following run, |
| on a system providing the NPTL threading implementation, |
| the stack size defaults to the value given by the |
| "stack size" resource limit: |
| .PP |
| .in +4n |
| .EX |
| .RB "$" " ulimit \-s" |
| 8192 # The stack size limit is 8 MB (0x800000 bytes) |
| .RB "$" " ./a.out hola salut servus" |
| Thread 1: top of stack near 0xb7dd03b8; argv_string=hola |
| Thread 2: top of stack near 0xb75cf3b8; argv_string=salut |
| Thread 3: top of stack near 0xb6dce3b8; argv_string=servus |
| Joined with thread 1; returned value was HOLA |
| Joined with thread 2; returned value was SALUT |
| Joined with thread 3; returned value was SERVUS |
| .EE |
| .in |
| .PP |
| In the next run, the program explicitly sets a stack size of 1\ MB (using |
| .BR pthread_attr_setstacksize (3)) |
| for the created threads: |
| .PP |
| .in +4n |
| .EX |
| .RB "$" " ./a.out \-s 0x100000 hola salut servus" |
| Thread 1: top of stack near 0xb7d723b8; argv_string=hola |
| Thread 2: top of stack near 0xb7c713b8; argv_string=salut |
| Thread 3: top of stack near 0xb7b703b8; argv_string=servus |
| Joined with thread 1; returned value was HOLA |
| Joined with thread 2; returned value was SALUT |
| Joined with thread 3; returned value was SERVUS |
| .EE |
| .in |
| .SS Program source |
| \& |
| .EX |
| #include <pthread.h> |
| #include <string.h> |
| #include <stdio.h> |
| #include <stdlib.h> |
| #include <unistd.h> |
| #include <errno.h> |
| #include <ctype.h> |
| |
| #define handle_error_en(en, msg) \e |
| do { errno = en; perror(msg); exit(EXIT_FAILURE); } while (0) |
| |
| #define handle_error(msg) \e |
| do { perror(msg); exit(EXIT_FAILURE); } while (0) |
| |
| struct thread_info { /* Used as argument to thread_start() */ |
| pthread_t thread_id; /* ID returned by pthread_create() */ |
| int thread_num; /* Application\-defined thread # */ |
| char *argv_string; /* From command\-line argument */ |
| }; |
| |
| /* Thread start function: display address near top of our stack, |
| and return upper\-cased copy of argv_string. */ |
| |
| static void * |
| thread_start(void *arg) |
| { |
| struct thread_info *tinfo = arg; |
| char *uargv; |
| |
| printf("Thread %d: top of stack near %p; argv_string=%s\en", |
| tinfo\->thread_num, (void *) &tinfo, tinfo\->argv_string); |
| |
| uargv = strdup(tinfo\->argv_string); |
| if (uargv == NULL) |
| handle_error("strdup"); |
| |
| for (char *p = uargv; *p != \(aq\e0\(aq; p++) |
| *p = toupper(*p); |
| |
| return uargv; |
| } |
| |
| int |
| main(int argc, char *argv[]) |
| { |
| int s, opt, num_threads; |
| pthread_attr_t attr; |
| ssize_t stack_size; |
| void *res; |
| |
| /* The "\-s" option specifies a stack size for our threads. */ |
| |
| stack_size = \-1; |
| while ((opt = getopt(argc, argv, "s:")) != \-1) { |
| switch (opt) { |
| case \(aqs\(aq: |
| stack_size = strtoul(optarg, NULL, 0); |
| break; |
| |
| default: |
| fprintf(stderr, "Usage: %s [\-s stack\-size] arg...\en", |
| argv[0]); |
| exit(EXIT_FAILURE); |
| } |
| } |
| |
| num_threads = argc \- optind; |
| |
| /* Initialize thread creation attributes. */ |
| |
| s = pthread_attr_init(&attr); |
| if (s != 0) |
| handle_error_en(s, "pthread_attr_init"); |
| |
| if (stack_size > 0) { |
| s = pthread_attr_setstacksize(&attr, stack_size); |
| if (s != 0) |
| handle_error_en(s, "pthread_attr_setstacksize"); |
| } |
| |
| /* Allocate memory for pthread_create() arguments. */ |
| |
| struct thread_info *tinfo = calloc(num_threads, sizeof(*tinfo)); |
| if (tinfo == NULL) |
| handle_error("calloc"); |
| |
| /* Create one thread for each command\-line argument. */ |
| |
| for (int tnum = 0; tnum < num_threads; tnum++) { |
| tinfo[tnum].thread_num = tnum + 1; |
| tinfo[tnum].argv_string = argv[optind + tnum]; |
| |
| /* The pthread_create() call stores the thread ID into |
| corresponding element of tinfo[]. */ |
| |
| s = pthread_create(&tinfo[tnum].thread_id, &attr, |
| &thread_start, &tinfo[tnum]); |
| if (s != 0) |
| handle_error_en(s, "pthread_create"); |
| } |
| |
| /* Destroy the thread attributes object, since it is no |
| longer needed. */ |
| |
| s = pthread_attr_destroy(&attr); |
| if (s != 0) |
| handle_error_en(s, "pthread_attr_destroy"); |
| |
| /* Now join with each thread, and display its returned value. */ |
| |
| for (int tnum = 0; tnum < num_threads; tnum++) { |
| s = pthread_join(tinfo[tnum].thread_id, &res); |
| if (s != 0) |
| handle_error_en(s, "pthread_join"); |
| |
| printf("Joined with thread %d; returned value was %s\en", |
| tinfo[tnum].thread_num, (char *) res); |
| free(res); /* Free memory allocated by thread */ |
| } |
| |
| free(tinfo); |
| exit(EXIT_SUCCESS); |
| } |
| .EE |
| .SH SEE ALSO |
| .ad l |
| .nh |
| .BR getrlimit (2), |
| .BR pthread_attr_init (3), |
| .BR pthread_cancel (3), |
| .BR pthread_detach (3), |
| .BR pthread_equal (3), |
| .BR pthread_exit (3), |
| .BR pthread_getattr_np (3), |
| .BR pthread_join (3), |
| .BR pthread_self (3), |
| .BR pthread_setattr_default_np (3), |
| .BR pthreads (7) |