PTHREADS(7) Linux Programmer’s Manual PTHREADS(7) 名前 pthreads - POSIX スレッド 説明 POSIX.1 は、一般に POSIX スレッドや Pthreads として知られるスレッド・プ ログラミングのインタフェース群 (関数、ヘッダファイル) を規定している 。 一 つのプロセスは複数のスレッドを持つことができ、全てのスレッドは同じプ ログラムを実行する。これらのスレッドは同じ大域メモリ (データとヒープ 領 域) を共有するが、各スレッドは自分専用のスタック (自動変数) を持つ。 POSIX.1 はスレッド間でどのような属性を共有するかについても定めている ( つまり、これらの属性はスレッド単位ではなくプロセス全体で共通である): - プロセス ID - 親プロセス ID - プロセスグループ ID とセッション ID - 制御端末 - ユーザ ID とグループ ID - オープンするファイルディスクリプタ - レコードのロック (fcntl(3) 参照) - シグナルの配置 - ファイルモード作成マスク (umask(2)) - カレント・ディレクトリ (chdir(2)) とルート・ディレクトリ (chroot(2)) - イ ン タ ー バ ル・タイマ (setitimer(2)) と POSIX タイマ (timer_cre- ate(2)) - nice 値 (setpriority(2)) - リソース制限 (setrlimit(2)) - CPU 時間 (times(2)) とリソース (getrusage(2)) の消費状況の計測 スタックについても、POSIX.1 はどのような属性が個々のスレッドで独立に 管 理されるかを規定している: - スレッド ID (pthread_t データ型) - シグナルマスク (pthread_sigmask(3)) - errno 変数 - 代替シグナルスタック (sigaltstack(2)) - リ ア ル タイム・スケジューリングのポリシーと優先度 (sched_setsched- uler(2) と sched_setparam(2)) 以下の Linux 特有の機能もスレッド単位である: - ケーパビリティ (capabilities(7) 参照) - CPU affinity (親和度) (sched_setaffinity(2)) pthreads 関数の返り値 ほとんどの pthreads 関数は成功すると 0 を返し、失敗した場合エラー番号を 返 す 。 pthreads 関 数 は errno をセットしない点に注意すること。 POSIX.1-2001 では、エラーを返す可能性のある pthreads 関数がエラー EINTR で失敗することは決してないと規定している。 スレッド ID あ るプロセス内の各スレッドは (pthread_t 型の) 一意なスレッド識別子を持 つ。この識別子は、 pthread_create(3) の呼び出し元に返される。また、スレ ッドは自身のスレッド識別子を pthread_self(3) を使って取得できる。スレッ ド ID の一意性が保証されるのは、一つのプロセス内においてのみである。 終 了 したスレッドが join された後では、スレッド ID は再利用される可能性が ある。スレッド ID を引き数に取る全てのスレッド関数において、その ID は 呼び出し元と同じプロセス内の一つのスレッドを参照する。 スレッドセーフな関数 ス レッドセーフな関数は、複数のスレッドから同時に呼び出しても安全な (す なわち、同時に呼び出されたかに関わらず、同じ結果を返す) 関数のことで あ る。 POSIX.1-2001 と POSIX.1-2008では、一部の例外を除き、標準で規定されてい る全ての関数がスレッドセーフであることを要求している。以下の関数が例 外 である。 asctime() basename() catgets() crypt() ctermid() (NULL でない引き数を渡された場合) 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 のみ (POSIX.1-2008 で削除された)] encrypt() endgrent() endpwent() endutxent() fcvt() [POSIX.1-2001 のみ (POSIX.1-2008 で削除された)] ftw() gcvt() [POSIX.1-2001 のみ (POSIX.1-2008 で削除された)] getc_unlocked() getchar_unlocked() getdate() getenv() getgrent() getgrgid() getgrnam() gethostbyaddr() [POSIX.1-2001 のみ (POSIX.1-2008 で削除された)] gethostbyname() [POSIX.1-2001 のみ (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() [POSIX.1-2008 で追加された] strtok() system() [POSIX.1-2008 で追加された] tmpnam() (NULL でない引き数を渡された場合) ttyname() unsetenv() wcrtomb() (最後の引き数が NULL の場合) wcsrtombs() (最後の引き数が NULL の場合) wcstombs() wctomb() 取り消しポイント (cancellation points) POSIX.1 の規定では、特定の関数は取り消しポイントでなければならず、他の 特定の関数は取り消しポイントであってもよいとされている。あるスレッド が 取り消し可能で、その取り消し種別 (cancelability type) が延期 (deferred) で、そのスレッドに対する取り消し要求が処理待ちの場合、取り消しポイン ト である関数を呼び出した時点で、そのスレッドのキャンセルが行われる。 POSIX.1-2001 と POSIX.1-2008 の両方、もしくはいずれか一方では、以下の関 数は、取り消しポイント (cancellation points) であることが必須となってい る。 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() [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 のみ (POSIX.1-2008 で削除された)] wait() waitid() waitpid() write() writev() POSIX.1-2001 と POSIX.1-2008 の両方、もしくはいずれか一方では、以下の関 数は、取り消しポイント (cancellation points) であってもよいことになって いる。 access() asctime() asctime_r() catclose() catgets() catopen() chmod() [POSIX.1-2008 で追加された] chown() [POSIX.1-2008 で追加された] closedir() closelog() ctermid() ctime() ctime_r() dbm_close() dbm_delete() dbm_fetch() dbm_nextkey() dbm_open() dbm_store() dlclose() dlopen() dprintf() [POSIX.1-2008 で追加された] endgrent() endhostent() endnetent() endprotoent() endpwent() endservent() endutxent() faccessat() [POSIX.1-2008 で追加された] fchmod() [POSIX.1-2008 で追加された] fchmodat() [POSIX.1-2008 で追加された] fchown() [POSIX.1-2008 で追加された] fchownat() [POSIX.1-2008 で追加された] fclose() fcntl() (cmd 引き数が何であっても) fflush() fgetc() fgetpos() fgets() fgetwc() fgetws() fmtmsg() fopen() fpathconf() fprintf() fputc() fputs() fputwc() fputws() fread() freopen() fscanf() fseek() fseeko() fsetpos() fstat() fstatat() [POSIX.1-2008 で追加された] ftell() ftello() ftw() futimens() [POSIX.1-2008 で追加された] fwprintf() fwrite() fwscanf() getaddrinfo() getc() getc_unlocked() getchar() getchar_unlocked() getcwd() getdate() getdelim() [POSIX.1-2008 で追加された] getgrent() getgrgid() getgrgid_r() getgrnam() getgrnam_r() gethostbyaddr() [SUSv3 のみ (この関数は POSIX.1-2008 で削除されている)] gethostbyname() [SUSv3 のみ (この関数は POSIX.1-2008 で削除されている)] gethostent() gethostid() gethostname() getline() [POSIX.1-2008 で追加された] getlogin() getlogin_r() getnameinfo() getnetbyaddr() getnetbyname() getnetent() getopt() (opterr が 0 以外の場合) getprotobyname() getprotobynumber() getprotoent() getpwent() getpwnam() getpwnam_r() getpwuid() getpwuid_r() gets() getservbyname() getservbyport() getservent() getutxent() getutxid() getutxline() getwc() getwchar() getwd() [SUSv3 のみ (この関数は POSIX.1-2008 で削除されている)] glob() iconv_close() iconv_open() ioctl() link() linkat() [POSIX.1-2008 で追加された] lio_listio() [POSIX.1-2008 で追加された] localtime() localtime_r() lockf() [POSIX.1-2008 で追加された] lseek() lstat() mkdir() [POSIX.1-2008 で追加された] mkdirat() [POSIX.1-2008 で追加された] mkdtemp() [POSIX.1-2008 で追加された] mkfifo() [POSIX.1-2008 で追加された] mkfifoat() [POSIX.1-2008 で追加された] mknod() [POSIX.1-2008 で追加された] mknodat() [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() [POSIX.1-2008 で追加された] psignal() [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() [POSIX.1-2008 で追加された] readlinkat() [POSIX.1-2008 で追加された] remove() rename() renameat() [POSIX.1-2008 で追加された] rewind() rewinddir() scandir() [POSIX.1-2008 で追加された] scanf() seekdir() semop() setgrent() sethostent() setnetent() setprotoent() setpwent() setservent() setutxent() sigpause() [POSIX.1-2008 で追加された] stat() strerror() strerror_r() strftime() symlink() symlinkat() [POSIX.1-2008 で追加された] sync() syslog() tmpfile() tmpnam() ttyname() ttyname_r() tzset() ungetc() ungetwc() unlink() unlinkat() [POSIX.1-2008 で追加された] utime() [POSIX.1-2008 で追加された] utimensat() [POSIX.1-2008 で追加された] utimes() [POSIX.1-2008 で追加された] vdprintf() [POSIX.1-2008 で追加された] vfprintf() vfwprintf() vprintf() vwprintf() wcsftime() wordexp() wprintf() wscanf() 実 装時に、標準規格で規定されていないその他の関数を取り消しポイントとす ることも認められている。特に、停止 (block) する可能性がある非標準の関数 を 取り消しポイントとする実装はあり得ることだろう (ファイルを扱う可能性 のあるほとんどの関数がこれに含まれる)。 Linux でのコンパイル Linux では、Pthreads API を用いたプログラムは cc -pthread でコンパイ ル すべきである。 POSIX スレッドの Linux での実装 これまで、2つのスレッドの実装が Linux の GNU C ライブラリにより提供され てきた。 LinuxThreads 最初の Pthreads の実装。 glibc 2.4 以降は、この実装はもはやサ ポ ートされていない。 NPTL (Native POSIX Threads Library) 新 し い Pthreads の 実 装。LinuxThreads と比べると、 NPTL は POSIX.1 の要求仕様への準拠の度合いが高く、多数のスレッドを作成し た 際 の 性能も高い。 NPTL は glibc 2.3.2 以降で利用可能である。 NPTL を利用するには Linux 2.6 カーネルに実装されている機能が必要 である。 どちらの実装もいわゆる 1:1 実装、すなわち個々のスレッドがカーネルのスケ ジューリング実体にマッピングされる。どちらのスレッドの実装も Linux の clone(2) システムコールを利用している。 NPTL では、スレッド同期の基本機 構 (mutex や スレッドの join 等) は Linux の futex(2) システムコール を 使って実装されている。 LinuxThreads この実装の大きな特徴は以下の通りである: - メ インスレッド (最初のスレッド) とプログラムが pthread_create(3) を 使って作成したスレッドに加え、この実装では「管理 (manager)」スレッド が作成される。管理スレッドはスレッドの作成と終了を取り扱う (このスレ ッドがうっかり kill されると、問題が起こることがある)。 - この実装では内部でシグナルを使用している。 Linux 2.2 以降では、リ ア ル タイムシグナルのうち最初の 3つが使われる (signal(7) 参照)。それ以 前のカーネルでは SIGUSR1 と SIGUSR2 が使われる。アプリケーションは、 スレッド実装で利用されているシグナルをどれも使わないようにしなければ ならない。 - スレッド間でプロセス ID を共有しない (実際には LinuxThreads のスレッ ドは通常よりは情報を共有するプロセスとして実装されているが、一つの共 通のプロセス ID を共有してはいない)。 (管理スレッドを 含 む) Linux- Threads スレッドは ps(1) を使うと別のプロセスのように見える。 LinuxThreads の実装では POSIX.1 仕様から逸脱している点がいくつかある。 以下に示すような点がある: - getpid(2) を呼び出したときに、スレッド毎に異なる値が返される。 - メインスレッド以外のスレッドで getppid(2) を呼び出すと、管理スレッド のプロセス ID が返される。本当は、これらのスレッドで getppid(2) を呼 んだ場合にはメインスレッドでの getppid(2) と同じ値が返るべきである。 - あ るスレッドが fork(2) を使って新しい子プロセスを作成した場合、どの スレッドでもこの子プロセスを wait(2) できるべきである。しかしなが ら 、 こ の 実 装では子プロセスを作成したスレッドだけがこの子プロセスを wait(2) できる。 - あるスレッドが execve(2) を呼び出した場合、他のスレッドは全て終了 さ れ る (POSIX.1 の仕様通り)。しかしながら、新しいプロセスは execve(2) を呼んだスレッドと同じ PID を持つ。正しくはメインスレッドと同じ PID を持つべきである。 - ス レ ッド間でユーザ ID とグループ ID が共有されないこのことは、set- user-ID プログラムで面倒な事態を招いたり、ア プ リ ケ ー シ ョ ン が seteuid(2) な ど を 使 って信用情報 (credentials) を変更した場合に Pthreads 関数が失敗する原因となる。 - スレッド間で共通のセッション ID やプロセスグループ ID を共有しない。 - スレッド間で fcntl(2) を使って作成されるレコード・ロックを共有しない 。 - times(2) と getrusage(2) が返す情報がプロセス全体の情報でなくスレ ッ ド単位の情報である。 - スレッド間でセマフォのアンドゥ値 (semop(2) 参照) を共有しない。 - スレッド間でインターバル・タイマを共有しない。 - スレッドは共通の nice 値を共有しない。 - POSXI.1 では、全体としてのプロセスに送られるシグナルと、個別のスレッ ドに送られるシグナルを区別して考えている。 POSIX.1 によると、プロ セ ス に送られたシグナル (例えば kill(2) を使って送る) は、そのプロセス に属すスレッドのうち勝手に (arbitrarily) に選択された一つのスレッ ド に より処理されることになっている。LinuxThreads はプロセスに送られる シグナルの概念に対応しておらず、シグナルは特定のスレッドにだけ送るこ とができる。 - スレッドはそれぞれの独自の代替シグナルスタックの設定を持つ。しかし、 新しいスレッドの代替シグナルスタックの設定はそのスレッドを作成したス レッドからコピーされ、そのためスレッドは最初は一つの代替シグナルスタ ックを共有する。 (仕様では、新しいスレッドは代替シグナルスタックが定 義されていない状態で開始されるべきとされている。 2つのスレッドが共有 されている代替シグナルスタック上で同時にシグナルの処理を行った場合、 予測不可能なプログラムのエラーが起こり得る。) NPTL NPTL では、一つのプロセスの全てのスレッドは同じスレッド・グループに属す る; スレッド・グループの全メンバーは同じ PID を共有する。 NPTL は管理ス レ ッド (manager thread) を利用しない。 NPTL は内部でリアルタイムシグナ ルのうち最初の 2つの番号を使用しており (signal(7) 参照)、これらのシグナ ルはアプリケーションでは使用できない。 NPTL にも POSIX.1 に準拠していない点が少なくとも一つある: - スレッドは共通の nice 値を共有しない。 NPTL の標準非準拠な点のうちいくつかは以前のカーネルでのみ発生する: - times(2) と getrusage(2) が返す情報がプロセス全体の情報でなくスレッ ド単位の情報である (カーネル 2.6.9 で修正された)。 - スレッド間でリソース制限を共有しない (カーネル 2.6.10 で修正され た) 。 - スレッド間でインターバル・タイマを共有しない (カーネル 2.6.12 で修正 された)。 - メインスレッドだけが setsid(2) を使って新しいセッションを開始する こ とができる (カーネル 2.6.16 で修正された)。 - メインスレッドだけが setpgid(2) を使ってそのプロセスをプロセス・グル ープ・リーダーにすることができる (カーネル 2.6.16 で修正された)。 - スレッドはそれぞれの独自の代替シグナルスタックの設定を持つ。しかし、 新しいスレッドの代替シグナルスタックの設定はそのスレッドを作成したス レッドからコピーされ、そのためスレッドは最初は一つの代替シグナルスタ ックを共有する (カーネル 2.6.16 で修正された)。 NPTL の実装では以下の点についても注意すること: - ス タ ッ ク サ イ ズ の リ ソースのソフト・リミット (setrlimit(2) の RLIMIT_STACK の説明を参照) が unlimited 以外の値に設定されている場合 、ソフト・リミットの値が新しいスレッドのデフォルトのスタックサイズと なる。設定を有効にするためには、プログラムを実行する前にリミット値を 設定しておかなければならない。たいていは、シェルの組み込みコマンドの ulimit -s (C シェルでは limit stacksize) を使って設定する。 スレッド実装の判定 glibc 2.3.2 以降では、 getconf(1) コマンドを使って、システムのスレッ ド 実装を判定することができる。以下に例を示す: bash$ getconf GNU_LIBPTHREAD_VERSION NPTL 2.3.4 ぞれ以前の glibc のバージョンでは、以下のようなコマンドでデフォルトのス レッド実装を判定することができる。 bash$ $( ldd /bin/ls | grep libc.so | awk '{print $3}' ) | \ egrep -i 'threads|ntpl' Native POSIX Threads Library by Ulrich Drepper et al スレッドの実装の選択: LD_ASSUME_KERNEL LinuxThreads と NPTL の両方をサポートしている glibc (glibc 2.3.x) が あ る システムでは、 LD_ASSUME_KERNEL 環境変数を使うことで、動的リンカがデ フォルトで選択するスレッド実装を上書きすることができる。この変数によ り 、 動的リンカが特定のバージョンのカーネル上で動作していると仮定するよう に指定する。 NPTL が必要とするサポート機能を提供していないカーネルバ ー ジ ョンを指定することで、強制的に LinuxThreads を使うことができる (この ようなことをする最もありそうな場面は、 LinuxThreads の標準非準拠な振 舞 いに依存する (壊れた) アプリケーションを動作させる場合だろう)。以下に例 を示す: bash$ $( LD_ASSUME_KERNEL=2.2.5 ldd /bin/ls | grep libc.so | \ awk '{print $3}' ) | egrep -i 'threads|ntpl' linuxthreads-0.10 by Xavier Leroy 関連項目 clone(2), futex(2), gettid(2), futex(7), signal(7), および Pthreads の各種マニュアルページ、例え ば: pthread_attr_init(3), pthread_atfork(3), pthread_cancel(3), pthread_cleanup_push(3), pthread_cond_signal(3), pthread_cond_wait(3), pthread_create(3), pthread_detach(3), pthread_equal(3), pthread_exit(3), pthread_key_cre- ate(3), pthread_kill(3), pthread_mutex_lock(3), pthread_mutex_unlock(3), pthread_once(3), pthread_setcancelstate(3), pthread_setcanceltype(3), pthread_setspecific(3), pthread_sigmask(3), pthread_testcancel(3) Linux 2008-11-18 PTHREADS(7)
PTHREADS(7) Linux Programmer’s Manual PTHREADS(7) NAME pthreads - POSIX threads 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 vari- ables). POSIX.1 also requires that threads share a range of other attributes (i.e., these attributes are process-wide rather than per-thread): - process ID - parent process ID - process group ID and session ID - controlling terminal - user and group IDs - open file descriptors - record locks (see fcntl(2)) - signal dispositions - file mode creation mask (umask(2)) - current directory (chdir(2)) and root directory (chroot(2)) - interval timers (setitimer(2)) and POSIX timers (timer_create(2)) - nice value (setpriority(2)) - resource limits (setrlimit(2)) - measurements of the consumption of CPU time (times(2)) and resources (getrusage(2)) As well as the stack, POSIX.1 specifies that various other attributes are distinct for each thread, including: - thread ID (the pthread_t data type) - signal mask (pthread_sigmask(3)) - the errno variable - alternate signal stack (sigaltstack(2)) - real-time scheduling policy and priority (sched_setscheduler(2) and sched_setparam(2)) The following Linux-specific features are also per-thread: - capabilities (see capabilities(7)) - CPU affinity (sched_setaffinity(2)) Pthreads function return values Most pthreads functions return 0 on success, and an error number of failure. Note that the pthreads functions do not set errno. For each of the pthreads functions that can return an error, POSIX.1-2001 speci- fies that the function can never fail with the error EINTR. Thread IDs Each of the threads in a process has a unique thread identifier (stored in the type pthread_t). This identifier is returned to the caller of pthread_create(3), and a thread can obtain its own thread identifier using pthread_self(3). Thread IDs are only guaranteed to be unique within a process. A thread ID may be reused after a terminated thread has been joined, or a detached thread has terminated. 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. 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. POSIX.1-2001 and POSIX.1-2008 require that all functions specified in the standard shall be thread-safe, except for the following functions: 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() Cancellation Points POSIX.1 specifies that certain functions must, and certain other func- tions may, be cancellation points. If a thread is cancelable, its can- celability 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. The following functions are required to be cancellation points by POSIX.1-2001 and/or POSIX.1-2008: 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() The following functions may be cancellation points according to POSIX.1-2001 and/or POSIX.1-2008: 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() [SUSv3 only (function removed in POSIX.1-2008)] gethostbyname() [SUSv3 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 non-zero) getprotobyname() getprotobynumber() getprotoent() getpwent() getpwnam() getpwnam_r() getpwuid() getpwuid_r() gets() getservbyname() getservbyport() getservent() getutxent() getutxid() getutxline() getwc() getwchar() getwd() [SUSv3 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() An implementation may also mark other functions not specified in the standard as cancellation points. In particular, an implementation is likely to mark any non-standard function that may block as a cancella- tion point. (This includes most functions that can touch files.) Compiling on Linux On Linux, programs that use the Pthreads API should be compiled using cc -pthread. Linux Implementations of POSIX Threads Over time, two threading implementations have been provided by the GNU C library on Linux: LinuxThreads This is the original Pthreads implementation. Since glibc 2.4, this implementation is no longer supported. NPTL (Native POSIX Threads Library) This is the modern Pthreads implementation. By comparison with LinuxThreads, NPTL provides closer conformance to the require- ments 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. Both of these are so-called 1:1 implementations, meaning that each thread maps to a kernel scheduling entity. Both threading implementa- tions employ the Linux clone(2) system call. In NPTL, thread synchro- nization primitives (mutexes, thread joining, etc.) are implemented using the Linux futex(2) system call. LinuxThreads The notable features of this implementation are the following: - In addition to the main (initial) thread, and the threads that the program creates using pthread_create(3), the implementation creates a "manager" thread. This thread handles thread creation and termi- nation. (Problems can result if this thread is inadvertently killed.) - Signals are used internally by the implementation. On Linux 2.2 and later, the first three real-time signals are used (see also sig- nal(7)). On older Linux kernels, SIGUSR1 and SIGUSR2 are used. Applications must avoid the use of whichever set of signals is employed by the implementation. - 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 pro- cesses using ps(1). The LinuxThreads implementation deviates from the POSIX.1 specification in a number of ways, including the following: - Calls to getpid(2) return a different value in each thread. - Calls to getppid(2) in threads other than the main thread return the process ID of the manager thread; instead getppid(2) in these threads should return the same value as getppid(2) in the main thread. - When one thread creates a new child process using fork(2), any thread should be able to wait(2) on the child. However, the imple- mentation only allows the thread that created the child to wait(2) on it. - When a thread calls 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 execve(2): it should have the same PID as the main thread. - Threads do not share user and group IDs. This can cause complica- tions with set-user-ID programs and can cause failures in Pthreads functions if an application changes its credentials using seteuid(2) or similar. - Threads do not share a common session ID and process group ID. - Threads do not share record locks created using fcntl(2). - The information returned by times(2) and getrusage(2) is per-thread rather than process-wide. - Threads do not share semaphore undo values (see semop(2)). - Threads do not share interval timers. - Threads do not share a common nice value. - 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 kill(2), for example) should be handled by a single, arbitrar- ily selected thread within the process. LinuxThreads does not sup- port the notion of process-directed signals: signals may only be sent to specific threads. - 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 alter- nate signal stack defined. If two threads handle signals on their shared alternate signal stack at the same time, unpredictable pro- gram failures are likely to occur.) NPTL With NPTL, all of the threads in a process are placed in the same thread group; all members of a thread groups share the same PID. NPTL does not employ a manager thread. NPTL makes internal use of the first two real-time signals (see also signal(7)); these signals cannot be used in applications. NPTL still has at least one non-conformance with POSIX.1: - Threads do not share a common nice value. Some NPTL non-conformances only occur with older kernels: - The information returned by times(2) and getrusage(2) is per-thread rather than process-wide (fixed in kernel 2.6.9). - Threads do not share resource limits (fixed in kernel 2.6.10). - Threads do not share interval timers (fixed in kernel 2.6.12). - Only the main thread is permitted to start a new session using set- sid(2) (fixed in kernel 2.6.16). - Only the main thread is permitted to make the process into a process group leader using setpgid(2) (fixed in kernel 2.6.16). - 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). Note the following further points about the NPTL implementation: - If the stack size soft resource limit (see the description of RLIMIT_STACK in setrlimit(2)) is set to a value other than unlim- ited, 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 ulimit -s shell built-in command (limit stacksize in the C shell). Determining the Threading Implementation Since glibc 2.3.2, the getconf(1) command can be used to determine the system’s threading implementation, for example: bash$ getconf GNU_LIBPTHREAD_VERSION NPTL 2.3.4 With older glibc versions, a command such as the following should be sufficient to determine the default threading implementation: bash$ $( ldd /bin/ls | grep libc.so | awk '{print $3}' ) | \ egrep -i 'threads|nptl' Native POSIX Threads Library by Ulrich Drepper et al Selecting the Threading Implementation: LD_ASSUME_KERNEL On systems with a glibc that supports both LinuxThreads and NPTL (i.e., glibc 2.3.x), the LD_ASSUME_KERNEL environment variable can be used to override the dynamic linker’s default choice of threading implementa- tion. This variable tells the dynamic linker to assume that it is run- ning 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 non-conformant behavior in LinuxThreads.) For example: bash$ $( LD_ASSUME_KERNEL=2.2.5 ldd /bin/ls | grep libc.so | \ awk '{print $3}' ) | egrep -i 'threads|ntpl' linuxthreads-0.10 by Xavier Leroy SEE ALSO clone(2), futex(2), gettid(2), proc(5), futex(7), signal(7), and various Pthreads manual pages, for example: pthread_attr_init(3), pthread_atfork(3), pthread_cancel(3), pthread_cleanup_push(3), pthread_cond_signal(3), pthread_cond_wait(3), pthread_create(3), pthread_detach(3), pthread_equal(3), pthread_exit(3), pthread_key_cre- ate(3), pthread_kill(3), pthread_mutex_lock(3), pthread_mutex_unlock(3), pthread_once(3), pthread_setcancelstate(3), pthread_setcanceltype(3), pthread_setspecific(3), pthread_sigmask(3), and pthread_testcancel(3) COLOPHON This page is part of release 3.22 of the Linux man-pages project. A description of the project, and information about reporting bugs, can be found at http://www.kernel.org/doc/man-pages/. Linux 2008-11-18 PTHREADS(7)
コロナウイルスの日ごとの感染者数・死者数をグラフ化してみました。どの国が増加傾向にあり、どの国が終息に向かっているかを視覚化しています。
Copyright(C) linux-cmd.com All Rights Reserved. Author Takayuki Yukawa