'\" t .\" Copyright (c) 2008 Linux Foundation, written by Michael Kerrisk .\" .\" .\" SPDX-License-Identifier: Linux-man-pages-copyleft .\" .TH pthread_create 3 2024-02-12 "Linux man-pages 6.7" .SH NAME pthread_create \- create a new thread .SH LIBRARY POSIX threads library .RI ( libpthread ", " \-lpthread ) .SH SYNOPSIS .nf .B #include .P .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 .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 (); .I arg is passed as the sole argument of .IR start_routine (). .P The new thread terminates in one of the following ways: .IP \[bu] 3 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 \[bu] 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 \[bu] It is canceled (see .BR pthread_cancel (3)). .IP \[bu] 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. .P 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. .P 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. .P 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)). .P The new thread inherits the calling thread's floating-point environment .RB ( fenv (3)). .P 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 .I *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 .B 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). .TS allbox; lbx lb lb l l l. Interface Attribute Value T{ .na .nh .BR pthread_create () T} Thread safety MT-Safe .TE .SH STANDARDS POSIX.1-2008. .SH HISTORY POSIX.1-2001. .SH NOTES See .BR pthread_self (3) for further information on the thread ID returned in .I *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\[em]the caller or the new thread\[em]will next execute. .P 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)). .P Under the NPTL threading implementation, if the .B RLIMIT_STACK soft resource limit .I 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 .B RLIMIT_STACK resource limit is set to "unlimited", a per-architecture value is used for the stack size: 2 MB on most architectures; 4 MB on POWER and Sparc-64. .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. .P 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: .P .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 .P In the next run, the program explicitly sets a stack size of 1\ MB (using .BR pthread_attr_setstacksize (3)) for the created threads: .P .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 \& .\" SRC BEGIN (pthread_create.c) .EX #include #include #include #include #include #include #include \& #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; void *res; size_t num_threads; ssize_t stack_size; pthread_attr_t attr; struct thread_info *tinfo; \& /* The "\-s" option specifies a stack size for our threads. */ \& stack_size = \-1; while ((opt = getopt(argc, argv, "s:")) != \-1) { switch (opt) { case \[aq]s\[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. */ \& tinfo = calloc(num_threads, sizeof(*tinfo)); if (tinfo == NULL) handle_error("calloc"); \& /* Create one thread for each command\-line argument. */ \& for (size_t 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 (size_t 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 .\" SRC END .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)