| .\" Copyright (c) 2005 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 PTHREADS 7 2021-03-22 "Linux" "Linux Programmer's Manual" |
| .SH NAME |
| pthreads \- POSIX threads |
| .SH DESCRIPTION |
| POSIX.1 specifies a set of interfaces (functions, header files) for |
| threaded programming commonly known as POSIX threads, or Pthreads. |
| A single process can contain multiple threads, |
| all of which are executing the same program. |
| These threads share the same global memory (data and heap segments), |
| but each thread has its own stack (automatic variables). |
| .PP |
| POSIX.1 also requires that threads share a range of other attributes |
| (i.e., these attributes are process-wide rather than per-thread): |
| .IP \- 3 |
| process ID |
| .IP \- 3 |
| parent process ID |
| .IP \- 3 |
| process group ID and session ID |
| .IP \- 3 |
| controlling terminal |
| .IP \- 3 |
| user and group IDs |
| .IP \- 3 |
| open file descriptors |
| .IP \- 3 |
| record locks (see |
| .BR fcntl (2)) |
| .IP \- 3 |
| signal dispositions |
| .IP \- 3 |
| file mode creation mask |
| .RB ( umask (2)) |
| .IP \- 3 |
| current directory |
| .RB ( chdir (2)) |
| and |
| root directory |
| .RB ( chroot (2)) |
| .IP \- 3 |
| interval timers |
| .RB ( setitimer (2)) |
| and POSIX timers |
| .RB ( timer_create (2)) |
| .IP \- 3 |
| nice value |
| .RB ( setpriority (2)) |
| .IP \- 3 |
| resource limits |
| .RB ( setrlimit (2)) |
| .IP \- 3 |
| measurements of the consumption of CPU time |
| .RB ( times (2)) |
| and resources |
| .RB ( getrusage (2)) |
| .PP |
| As well as the stack, POSIX.1 specifies that various other |
| attributes are distinct for each thread, including: |
| .IP \- 3 |
| thread ID (the |
| .I pthread_t |
| data type) |
| .IP \- 3 |
| signal mask |
| .RB ( pthread_sigmask (3)) |
| .IP \- 3 |
| the |
| .I errno |
| variable |
| .IP \- 3 |
| alternate signal stack |
| .RB ( sigaltstack (2)) |
| .IP \- 3 |
| real-time scheduling policy and priority |
| .RB ( sched (7)) |
| .PP |
| The following Linux-specific features are also per-thread: |
| .IP \- 3 |
| capabilities (see |
| .BR capabilities (7)) |
| .IP \- 3 |
| CPU affinity |
| .RB ( sched_setaffinity (2)) |
| .SS Pthreads function return values |
| Most pthreads functions return 0 on success, and an error number on failure. |
| The error numbers that can be returned have the same meaning as |
| the error numbers returned in |
| .I errno |
| by conventional system calls and C library functions. |
| Note that the pthreads functions do not set |
| .IR errno . |
| For each of the pthreads functions that can return an error, |
| POSIX.1-2001 specifies that the function can never fail with the error |
| .BR EINTR . |
| .SS Thread IDs |
| Each of the threads in a process has a unique thread identifier |
| (stored in the type |
| .IR pthread_t ). |
| This identifier is returned to the caller of |
| .BR pthread_create (3), |
| and a thread can obtain its own thread identifier using |
| .BR pthread_self (3). |
| .PP |
| Thread IDs are guaranteed to be unique only within a process. |
| (In all pthreads functions that accept a thread ID as an argument, |
| that ID by definition refers to a thread in |
| the same process as the caller.) |
| .PP |
| The system may reuse a thread ID after a terminated thread has been joined, |
| or a detached thread has terminated. |
| POSIX says: "If an application attempts to use a thread ID whose |
| lifetime has ended, the behavior is undefined." |
| .SS Thread-safe functions |
| A thread-safe function is one that can be safely |
| (i.e., it will deliver the same results regardless of whether it is) |
| called from multiple threads at the same time. |
| .PP |
| POSIX.1-2001 and POSIX.1-2008 require that all functions specified |
| in the standard shall be thread-safe, |
| except for the following functions: |
| .PP |
| .in +4n |
| .EX |
| asctime() |
| basename() |
| catgets() |
| crypt() |
| ctermid() if passed a non-NULL argument |
| ctime() |
| dbm_clearerr() |
| dbm_close() |
| dbm_delete() |
| dbm_error() |
| dbm_fetch() |
| dbm_firstkey() |
| dbm_nextkey() |
| dbm_open() |
| dbm_store() |
| dirname() |
| dlerror() |
| drand48() |
| ecvt() [POSIX.1-2001 only (function removed in POSIX.1-2008)] |
| encrypt() |
| endgrent() |
| endpwent() |
| endutxent() |
| fcvt() [POSIX.1-2001 only (function removed in POSIX.1-2008)] |
| ftw() |
| gcvt() [POSIX.1-2001 only (function removed in POSIX.1-2008)] |
| getc_unlocked() |
| getchar_unlocked() |
| getdate() |
| getenv() |
| getgrent() |
| getgrgid() |
| getgrnam() |
| gethostbyaddr() [POSIX.1-2001 only (function removed in |
| POSIX.1-2008)] |
| gethostbyname() [POSIX.1-2001 only (function removed in |
| POSIX.1-2008)] |
| gethostent() |
| getlogin() |
| getnetbyaddr() |
| getnetbyname() |
| getnetent() |
| getopt() |
| getprotobyname() |
| getprotobynumber() |
| getprotoent() |
| getpwent() |
| getpwnam() |
| getpwuid() |
| getservbyname() |
| getservbyport() |
| getservent() |
| getutxent() |
| getutxid() |
| getutxline() |
| gmtime() |
| hcreate() |
| hdestroy() |
| hsearch() |
| inet_ntoa() |
| l64a() |
| lgamma() |
| lgammaf() |
| lgammal() |
| localeconv() |
| localtime() |
| lrand48() |
| mrand48() |
| nftw() |
| nl_langinfo() |
| ptsname() |
| putc_unlocked() |
| putchar_unlocked() |
| putenv() |
| pututxline() |
| rand() |
| readdir() |
| setenv() |
| setgrent() |
| setkey() |
| setpwent() |
| setutxent() |
| strerror() |
| strsignal() [Added in POSIX.1-2008] |
| strtok() |
| system() [Added in POSIX.1-2008] |
| tmpnam() if passed a non-NULL argument |
| ttyname() |
| unsetenv() |
| wcrtomb() if its final argument is NULL |
| wcsrtombs() if its final argument is NULL |
| wcstombs() |
| wctomb() |
| .EE |
| .in |
| .SS Async-cancel-safe functions |
| An async-cancel-safe function is one that can be safely called |
| in an application where asynchronous cancelability is enabled (see |
| .BR pthread_setcancelstate (3)). |
| .PP |
| Only the following functions are required to be async-cancel-safe by |
| POSIX.1-2001 and POSIX.1-2008: |
| .PP |
| .in +4n |
| .EX |
| pthread_cancel() |
| pthread_setcancelstate() |
| pthread_setcanceltype() |
| .EE |
| .in |
| .SS Cancellation points |
| POSIX.1 specifies that certain functions must, |
| and certain other functions may, be cancellation points. |
| If a thread is cancelable, its cancelability type is deferred, |
| and a cancellation request is pending for the thread, |
| then the thread is canceled when it calls a function |
| that is a cancellation point. |
| .PP |
| The following functions are required to be cancellation points by |
| POSIX.1-2001 and/or POSIX.1-2008: |
| .PP |
| .\" FIXME |
| .\" Document the list of all functions that are cancellation points in glibc |
| .in +4n |
| .EX |
| accept() |
| aio_suspend() |
| clock_nanosleep() |
| close() |
| connect() |
| creat() |
| fcntl() F_SETLKW |
| fdatasync() |
| fsync() |
| getmsg() |
| getpmsg() |
| lockf() F_LOCK |
| mq_receive() |
| mq_send() |
| mq_timedreceive() |
| mq_timedsend() |
| msgrcv() |
| msgsnd() |
| msync() |
| nanosleep() |
| open() |
| openat() [Added in POSIX.1-2008] |
| pause() |
| poll() |
| pread() |
| pselect() |
| pthread_cond_timedwait() |
| pthread_cond_wait() |
| pthread_join() |
| pthread_testcancel() |
| putmsg() |
| putpmsg() |
| pwrite() |
| read() |
| readv() |
| recv() |
| recvfrom() |
| recvmsg() |
| select() |
| sem_timedwait() |
| sem_wait() |
| send() |
| sendmsg() |
| sendto() |
| sigpause() [POSIX.1-2001 only (moves to "may" list in POSIX.1-2008)] |
| sigsuspend() |
| sigtimedwait() |
| sigwait() |
| sigwaitinfo() |
| sleep() |
| system() |
| tcdrain() |
| usleep() [POSIX.1-2001 only (function removed in POSIX.1-2008)] |
| wait() |
| waitid() |
| waitpid() |
| write() |
| writev() |
| .EE |
| .in |
| .PP |
| The following functions may be cancellation points according to |
| POSIX.1-2001 and/or POSIX.1-2008: |
| .PP |
| .in +4n |
| .EX |
| access() |
| asctime() |
| asctime_r() |
| catclose() |
| catgets() |
| catopen() |
| chmod() [Added in POSIX.1-2008] |
| chown() [Added in POSIX.1-2008] |
| closedir() |
| closelog() |
| ctermid() |
| ctime() |
| ctime_r() |
| dbm_close() |
| dbm_delete() |
| dbm_fetch() |
| dbm_nextkey() |
| dbm_open() |
| dbm_store() |
| dlclose() |
| dlopen() |
| dprintf() [Added in POSIX.1-2008] |
| endgrent() |
| endhostent() |
| endnetent() |
| endprotoent() |
| endpwent() |
| endservent() |
| endutxent() |
| faccessat() [Added in POSIX.1-2008] |
| fchmod() [Added in POSIX.1-2008] |
| fchmodat() [Added in POSIX.1-2008] |
| fchown() [Added in POSIX.1-2008] |
| fchownat() [Added in POSIX.1-2008] |
| fclose() |
| fcntl() (for any value of cmd argument) |
| fflush() |
| fgetc() |
| fgetpos() |
| fgets() |
| fgetwc() |
| fgetws() |
| fmtmsg() |
| fopen() |
| fpathconf() |
| fprintf() |
| fputc() |
| fputs() |
| fputwc() |
| fputws() |
| fread() |
| freopen() |
| fscanf() |
| fseek() |
| fseeko() |
| fsetpos() |
| fstat() |
| fstatat() [Added in POSIX.1-2008] |
| ftell() |
| ftello() |
| ftw() |
| futimens() [Added in POSIX.1-2008] |
| fwprintf() |
| fwrite() |
| fwscanf() |
| getaddrinfo() |
| getc() |
| getc_unlocked() |
| getchar() |
| getchar_unlocked() |
| getcwd() |
| getdate() |
| getdelim() [Added in POSIX.1-2008] |
| getgrent() |
| getgrgid() |
| getgrgid_r() |
| getgrnam() |
| getgrnam_r() |
| gethostbyaddr() [POSIX.1-2001 only (function removed in |
| POSIX.1-2008)] |
| gethostbyname() [POSIX.1-2001 only (function removed in |
| POSIX.1-2008)] |
| gethostent() |
| gethostid() |
| gethostname() |
| getline() [Added in POSIX.1-2008] |
| getlogin() |
| getlogin_r() |
| getnameinfo() |
| getnetbyaddr() |
| getnetbyname() |
| getnetent() |
| getopt() (if opterr is nonzero) |
| getprotobyname() |
| getprotobynumber() |
| getprotoent() |
| getpwent() |
| getpwnam() |
| getpwnam_r() |
| getpwuid() |
| getpwuid_r() |
| gets() |
| getservbyname() |
| getservbyport() |
| getservent() |
| getutxent() |
| getutxid() |
| getutxline() |
| getwc() |
| getwchar() |
| getwd() [POSIX.1-2001 only (function removed in POSIX.1-2008)] |
| glob() |
| iconv_close() |
| iconv_open() |
| ioctl() |
| link() |
| linkat() [Added in POSIX.1-2008] |
| lio_listio() [Added in POSIX.1-2008] |
| localtime() |
| localtime_r() |
| lockf() [Added in POSIX.1-2008] |
| lseek() |
| lstat() |
| mkdir() [Added in POSIX.1-2008] |
| mkdirat() [Added in POSIX.1-2008] |
| mkdtemp() [Added in POSIX.1-2008] |
| mkfifo() [Added in POSIX.1-2008] |
| mkfifoat() [Added in POSIX.1-2008] |
| mknod() [Added in POSIX.1-2008] |
| mknodat() [Added in POSIX.1-2008] |
| mkstemp() |
| mktime() |
| nftw() |
| opendir() |
| openlog() |
| pathconf() |
| pclose() |
| perror() |
| popen() |
| posix_fadvise() |
| posix_fallocate() |
| posix_madvise() |
| posix_openpt() |
| posix_spawn() |
| posix_spawnp() |
| posix_trace_clear() |
| posix_trace_close() |
| posix_trace_create() |
| posix_trace_create_withlog() |
| posix_trace_eventtypelist_getnext_id() |
| posix_trace_eventtypelist_rewind() |
| posix_trace_flush() |
| posix_trace_get_attr() |
| posix_trace_get_filter() |
| posix_trace_get_status() |
| posix_trace_getnext_event() |
| posix_trace_open() |
| posix_trace_rewind() |
| posix_trace_set_filter() |
| posix_trace_shutdown() |
| posix_trace_timedgetnext_event() |
| posix_typed_mem_open() |
| printf() |
| psiginfo() [Added in POSIX.1-2008] |
| psignal() [Added in POSIX.1-2008] |
| pthread_rwlock_rdlock() |
| pthread_rwlock_timedrdlock() |
| pthread_rwlock_timedwrlock() |
| pthread_rwlock_wrlock() |
| putc() |
| putc_unlocked() |
| putchar() |
| putchar_unlocked() |
| puts() |
| pututxline() |
| putwc() |
| putwchar() |
| readdir() |
| readdir_r() |
| readlink() [Added in POSIX.1-2008] |
| readlinkat() [Added in POSIX.1-2008] |
| remove() |
| rename() |
| renameat() [Added in POSIX.1-2008] |
| rewind() |
| rewinddir() |
| scandir() [Added in POSIX.1-2008] |
| scanf() |
| seekdir() |
| semop() |
| setgrent() |
| sethostent() |
| setnetent() |
| setprotoent() |
| setpwent() |
| setservent() |
| setutxent() |
| sigpause() [Added in POSIX.1-2008] |
| stat() |
| strerror() |
| strerror_r() |
| strftime() |
| symlink() |
| symlinkat() [Added in POSIX.1-2008] |
| sync() |
| syslog() |
| tmpfile() |
| tmpnam() |
| ttyname() |
| ttyname_r() |
| tzset() |
| ungetc() |
| ungetwc() |
| unlink() |
| unlinkat() [Added in POSIX.1-2008] |
| utime() [Added in POSIX.1-2008] |
| utimensat() [Added in POSIX.1-2008] |
| utimes() [Added in POSIX.1-2008] |
| vdprintf() [Added in POSIX.1-2008] |
| vfprintf() |
| vfwprintf() |
| vprintf() |
| vwprintf() |
| wcsftime() |
| wordexp() |
| wprintf() |
| wscanf() |
| .EE |
| .in |
| .PP |
| An implementation may also mark other functions |
| not specified in the standard as cancellation points. |
| In particular, an implementation is likely to mark |
| any nonstandard function that may block as a cancellation point. |
| (This includes most functions that can touch files.) |
| .PP |
| It should be noted that even if an application is not using |
| asynchronous cancellation, that calling a function from the above list |
| from an asynchronous signal handler may cause the equivalent of |
| asynchronous cancellation. |
| The underlying user code may not expect |
| asynchronous cancellation and the state of the user data may become |
| inconsistent. |
| Therefore signals should be used with caution when |
| entering a region of deferred cancellation. |
| .\" So, scanning "cancellation point" comments in the glibc 2.8 header |
| .\" files, it looks as though at least the following nonstandard |
| .\" functions are cancellation points: |
| .\" endnetgrent |
| .\" endspent |
| .\" epoll_pwait |
| .\" epoll_wait |
| .\" fcloseall |
| .\" fdopendir |
| .\" fflush_unlocked |
| .\" fgetc_unlocked |
| .\" fgetgrent |
| .\" fgetgrent_r |
| .\" fgetpwent |
| .\" fgetpwent_r |
| .\" fgets_unlocked |
| .\" fgetspent |
| .\" fgetspent_r |
| .\" fgetwc_unlocked |
| .\" fgetws_unlocked |
| .\" fputc_unlocked |
| .\" fputs_unlocked |
| .\" fputwc_unlocked |
| .\" fputws_unlocked |
| .\" fread_unlocked |
| .\" fwrite_unlocked |
| .\" gai_suspend |
| .\" getaddrinfo_a |
| .\" getdate_r |
| .\" getgrent_r |
| .\" getgrouplist |
| .\" gethostbyaddr_r |
| .\" gethostbyname2 |
| .\" gethostbyname2_r |
| .\" gethostbyname_r |
| .\" gethostent_r |
| .\" getnetbyaddr_r |
| .\" getnetbyname_r |
| .\" getnetent_r |
| .\" getnetgrent |
| .\" getnetgrent_r |
| .\" getprotobyname_r |
| .\" getprotobynumber_r |
| .\" getprotoent_r |
| .\" getpw |
| .\" getpwent_r |
| .\" getservbyname_r |
| .\" getservbyport_r |
| .\" getservent_r |
| .\" getspent |
| .\" getspent_r |
| .\" getspnam |
| .\" getspnam_r |
| .\" getutmp |
| .\" getutmpx |
| .\" getw |
| .\" getwc_unlocked |
| .\" getwchar_unlocked |
| .\" initgroups |
| .\" innetgr |
| .\" mkostemp |
| .\" mkostemp64 |
| .\" mkstemp64 |
| .\" ppoll |
| .\" pthread_timedjoin_np |
| .\" putgrent |
| .\" putpwent |
| .\" putspent |
| .\" putw |
| .\" putwc_unlocked |
| .\" putwchar_unlocked |
| .\" rcmd |
| .\" rcmd_af |
| .\" rexec |
| .\" rexec_af |
| .\" rresvport |
| .\" rresvport_af |
| .\" ruserok |
| .\" ruserok_af |
| .\" setnetgrent |
| .\" setspent |
| .\" sgetspent |
| .\" sgetspent_r |
| .\" updwtmpx |
| .\" utmpxname |
| .\" vfscanf |
| .\" vfwscanf |
| .\" vscanf |
| .\" vsyslog |
| .\" vwscanf |
| .SS Compiling on Linux |
| On Linux, programs that use the Pthreads API should be compiled using |
| .IR "cc \-pthread" . |
| .SS Linux implementations of POSIX threads |
| Over time, two threading implementations have been provided by |
| the GNU C library on Linux: |
| .TP |
| .B LinuxThreads |
| This is the original Pthreads implementation. |
| Since glibc 2.4, this implementation is no longer supported. |
| .TP |
| .BR NPTL " (Native POSIX Threads Library)" |
| This is the modern Pthreads implementation. |
| By comparison with LinuxThreads, NPTL provides closer conformance to |
| the requirements of the POSIX.1 specification and better performance |
| when creating large numbers of threads. |
| NPTL is available since glibc 2.3.2, |
| and requires features that are present in the Linux 2.6 kernel. |
| .PP |
| Both of these are so-called 1:1 implementations, meaning that each |
| thread maps to a kernel scheduling entity. |
| Both threading implementations employ the Linux |
| .BR clone (2) |
| system call. |
| In NPTL, thread synchronization primitives (mutexes, |
| thread joining, and so on) are implemented using the Linux |
| .BR futex (2) |
| system call. |
| .SS LinuxThreads |
| The notable features of this implementation are the following: |
| .IP \- 3 |
| In addition to the main (initial) thread, |
| and the threads that the program creates using |
| .BR pthread_create (3), |
| the implementation creates a "manager" thread. |
| This thread handles thread creation and termination. |
| (Problems can result if this thread is inadvertently killed.) |
| .IP \- 3 |
| Signals are used internally by the implementation. |
| On Linux 2.2 and later, the first three real-time signals are used |
| (see also |
| .BR signal (7)). |
| On older Linux kernels, |
| .B SIGUSR1 |
| and |
| .B SIGUSR2 |
| are used. |
| Applications must avoid the use of whichever set of signals is |
| employed by the implementation. |
| .IP \- 3 |
| Threads do not share process IDs. |
| (In effect, LinuxThreads threads are implemented as processes which share |
| more information than usual, but which do not share a common process ID.) |
| LinuxThreads threads (including the manager thread) |
| are visible as separate processes using |
| .BR ps (1). |
| .PP |
| The LinuxThreads implementation deviates from the POSIX.1 |
| specification in a number of ways, including the following: |
| .IP \- 3 |
| Calls to |
| .BR getpid (2) |
| return a different value in each thread. |
| .IP \- 3 |
| Calls to |
| .BR getppid (2) |
| in threads other than the main thread return the process ID of the |
| manager thread; instead |
| .BR getppid (2) |
| in these threads should return the same value as |
| .BR getppid (2) |
| in the main thread. |
| .IP \- 3 |
| When one thread creates a new child process using |
| .BR fork (2), |
| any thread should be able to |
| .BR wait (2) |
| on the child. |
| However, the implementation allows only the thread that |
| created the child to |
| .BR wait (2) |
| on it. |
| .IP \- 3 |
| When a thread calls |
| .BR execve (2), |
| all other threads are terminated (as required by POSIX.1). |
| However, the resulting process has the same PID as the thread that called |
| .BR execve (2): |
| it should have the same PID as the main thread. |
| .IP \- 3 |
| Threads do not share user and group IDs. |
| This can cause complications with set-user-ID programs and |
| can cause failures in Pthreads functions if an application |
| changes its credentials using |
| .BR seteuid (2) |
| or similar. |
| .IP \- 3 |
| Threads do not share a common session ID and process group ID. |
| .IP \- 3 |
| Threads do not share record locks created using |
| .BR fcntl (2). |
| .IP \- 3 |
| The information returned by |
| .BR times (2) |
| and |
| .BR getrusage (2) |
| is per-thread rather than process-wide. |
| .IP \- 3 |
| Threads do not share semaphore undo values (see |
| .BR semop (2)). |
| .IP \- 3 |
| Threads do not share interval timers. |
| .IP \- 3 |
| Threads do not share a common nice value. |
| .IP \- 3 |
| POSIX.1 distinguishes the notions of signals that are directed |
| to the process as a whole and signals that are directed to individual |
| threads. |
| According to POSIX.1, a process-directed signal (sent using |
| .BR kill (2), |
| for example) should be handled by a single, |
| arbitrarily selected thread within the process. |
| LinuxThreads does not support the notion of process-directed signals: |
| signals may be sent only to specific threads. |
| .IP \- 3 |
| Threads have distinct alternate signal stack settings. |
| However, a new thread's alternate signal stack settings |
| are copied from the thread that created it, so that |
| the threads initially share an alternate signal stack. |
| (A new thread should start with no alternate signal stack defined. |
| If two threads handle signals on their shared alternate signal |
| stack at the same time, unpredictable program failures are |
| likely to occur.) |
| .SS NPTL |
| With NPTL, all of the threads in a process are placed |
| in the same thread group; |
| all members of a thread group share the same PID. |
| NPTL does not employ a manager thread. |
| .PP |
| NPTL makes internal use of the first two real-time signals; |
| these signals cannot be used in applications. |
| See |
| .BR nptl (7) |
| for further details. |
| .PP |
| NPTL still has at least one nonconformance with POSIX.1: |
| .IP \- 3 |
| Threads do not share a common nice value. |
| .\" FIXME . bug report filed for NPTL nice nonconformance |
| .\" http://bugzilla.kernel.org/show_bug.cgi?id=6258 |
| .\" Sep 08: there is a patch by Denys Vlasenko to address this |
| .\" "make setpriority POSIX compliant; introduce PRIO_THREAD extension" |
| .\" Monitor this to see if it makes it into mainline. |
| .PP |
| Some NPTL nonconformances occur only with older kernels: |
| .IP \- 3 |
| The information returned by |
| .BR times (2) |
| and |
| .BR getrusage (2) |
| is per-thread rather than process-wide (fixed in kernel 2.6.9). |
| .IP \- 3 |
| Threads do not share resource limits (fixed in kernel 2.6.10). |
| .IP \- 3 |
| Threads do not share interval timers (fixed in kernel 2.6.12). |
| .IP \- 3 |
| Only the main thread is permitted to start a new session using |
| .BR setsid (2) |
| (fixed in kernel 2.6.16). |
| .IP \- 3 |
| Only the main thread is permitted to make the process into a |
| process group leader using |
| .BR setpgid (2) |
| (fixed in kernel 2.6.16). |
| .IP \- 3 |
| Threads have distinct alternate signal stack settings. |
| However, a new thread's alternate signal stack settings |
| are copied from the thread that created it, so that |
| the threads initially share an alternate signal stack |
| (fixed in kernel 2.6.16). |
| .PP |
| Note the following further points about the NPTL implementation: |
| .IP \- 3 |
| If the stack size soft resource limit (see the description of |
| .B RLIMIT_STACK |
| in |
| .BR setrlimit (2)) |
| is set to a value other than |
| .IR unlimited , |
| then this value defines the default stack size for new threads. |
| To be effective, this limit must be set before the program |
| is executed, perhaps using the |
| .I ulimit \-s |
| shell built-in command |
| .RI ( "limit stacksize" |
| in the C shell). |
| .SS Determining the threading implementation |
| Since glibc 2.3.2, the |
| .BR getconf (1) |
| command can be used to determine |
| the system's threading implementation, for example: |
| .PP |
| .in +4n |
| .EX |
| bash$ getconf GNU_LIBPTHREAD_VERSION |
| NPTL 2.3.4 |
| .EE |
| .in |
| .PP |
| With older glibc versions, a command such as the following should |
| be sufficient to determine the default threading implementation: |
| .PP |
| .in +4n |
| .EX |
| bash$ $( ldd /bin/ls | grep libc.so | awk \(aq{print $3}\(aq ) | \e |
| egrep \-i \(aqthreads|nptl\(aq |
| Native POSIX Threads Library by Ulrich Drepper et al |
| .EE |
| .in |
| .SS Selecting the threading implementation: LD_ASSUME_KERNEL |
| On systems with a glibc that supports both LinuxThreads and NPTL |
| (i.e., glibc 2.3.\fIx\fP), the |
| .B LD_ASSUME_KERNEL |
| environment variable can be used to override |
| the dynamic linker's default choice of threading implementation. |
| This variable tells the dynamic linker to assume that it is |
| running on top of a particular kernel version. |
| By specifying a kernel version that does not |
| provide the support required by NPTL, we can force the use |
| of LinuxThreads. |
| (The most likely reason for doing this is to run a |
| (broken) application that depends on some nonconformant behavior |
| in LinuxThreads.) |
| For example: |
| .PP |
| .in +4n |
| .EX |
| bash$ $( LD_ASSUME_KERNEL=2.2.5 ldd /bin/ls | grep libc.so | \e |
| awk \(aq{print $3}\(aq ) | egrep \-i \(aqthreads|nptl\(aq |
| linuxthreads\-0.10 by Xavier Leroy |
| .EE |
| .in |
| .SH SEE ALSO |
| .ad l |
| .nh |
| .BR clone (2), |
| .BR fork (2), |
| .BR futex (2), |
| .BR gettid (2), |
| .BR proc (5), |
| .BR attributes (7), |
| .BR futex (7), |
| .BR nptl (7), |
| .BR sigevent (7), |
| .BR signal (7) |
| .PP |
| Various Pthreads manual pages, for example: |
| .BR pthread_atfork (3), |
| .BR pthread_attr_init (3), |
| .BR pthread_cancel (3), |
| .BR pthread_cleanup_push (3), |
| .BR pthread_cond_signal (3), |
| .BR pthread_cond_wait (3), |
| .BR pthread_create (3), |
| .BR pthread_detach (3), |
| .BR pthread_equal (3), |
| .BR pthread_exit (3), |
| .BR pthread_key_create (3), |
| .BR pthread_kill (3), |
| .BR pthread_mutex_lock (3), |
| .BR pthread_mutex_unlock (3), |
| .BR pthread_mutexattr_destroy (3), |
| .BR pthread_mutexattr_init (3), |
| .BR pthread_once (3), |
| .BR pthread_spin_init (3), |
| .BR pthread_spin_lock (3), |
| .BR pthread_rwlockattr_setkind_np (3), |
| .BR pthread_setcancelstate (3), |
| .BR pthread_setcanceltype (3), |
| .BR pthread_setspecific (3), |
| .BR pthread_sigmask (3), |
| .BR pthread_sigqueue (3), |
| and |
| .BR pthread_testcancel (3) |