Provided by: manpages-ja-dev_0.5.0.0.20221215+dfsg-1_all bug

名前

       pthread_create - 新しいスレッドを作成する

書式

       #include <pthread.h>

       int pthread_create(pthread_t *thread, const pthread_attr_t *attr,
                          void *(*start_routine) (void *), void *arg);

       -pthread を付けてコンパイルとリンクを行う。

説明

       pthread_create() 関数は、呼び出したプロセス内に新しいスレッドを作成する。 新しいスレッドの
       実行は、 start_routine() を起動することで開始される。  start_routine()  は引数を一つだけ取
       り、 argstart_routine() の引数として渡される。

       新しく作成されたスレッドは、以下のいずれかで終了する。

       * スレッドが pthread_exit(3) を呼び出す。 pthread_exit(3) を呼び出す際には終了ステータス値
         を指定する。 この値は pthread_join(3) を呼び出した同じプロセス内の  別のスレッドで参照で
         きる。

       * スレッドが start_routine() から返る。これは、 return 文に渡した値で pthread_exit(3) を呼
         び出すのと等価である。

       * スレッドがキャンセルされる (pthread_cancel(3) 参照)。

       * プロセス内のいずれかのスレッドで exit(3)  が呼ばれるか、  メインスレッドで  main()  内で
         return が実行される。 この場合は、プロセス内の全てのスレッドが終了される。

       attr  引数は pthread_attr_t 構造体へのポインターであり、 pthread_attr_t 構造体の内容を使用
       して、スレッド作成時に           新しいスレッドの属性が決定される。           この構造体は
       pthread_attr_init(3)  や関連の関数を使って初期化される。 attr が NULL の場合、新しいスレッ
       ドはデフォルトの属性で作成される。

       成功した場合は、 pthread_create() は返る前に新しいスレッドの ID を thread が指すバッファー
       に格納する。この ID は、これ以降に他の pthreads 関数の呼び出しでスレッドを参照するのに使用
       される。

       新しいスレッドは、スレッドを作成したスレッドのシグナルマスク (pthread_sigmask(3) 参照)  の
       コピーを継承する。  新しいスレッドの処理待ちシグナル (sigpending(2)) の集合は空となる。 新
       しいスレッドはスレッドを作成したスレッドの代替シグナルスタック (sigaltstack(2)) を継承しな
       い。

       新しいスレッドは呼び出したスレッドの浮動小数点環境 (fenv(3)) を継承する。

       新しいスレッドの CPU 時間時計の初期値は 0 である (pthread_getcpuclockid(3) 参照)。

   Linux 固有の詳細
       新しいスレッドは、呼び出したスレッドの  ケーパビリティセット (capabilities(7) 参照) と CPU
       affinity マスク (sched_setaffinity(2) 参照) の コピーをを継承しない。

返り値

       成功すると、 pthread_create() は 0 を返す。  エラーの場合は、エラー番号が返され、  *thread
       の内容は不定である。

エラー

       EAGAIN 別のスレッドを作成するのに十分なリソースがない。

       EAGAIN システムで設定されたスレッド数の上限に達していた。 このエラーの原因となる上限値はい
              くつかある。 実ユーザー ID 当たりのプロセス数とスレッド数の上限である、ソフトリソー
              ス上限 RLIMIT_NPROC に達していた (setrlimit(2) で設定できる)。 カーネルのシステム全
              体のプロセスとスレッドの数の上限値である /proc/sys/kernel/threads-max  が達していた
              (proc(5)  参照)。  PID  の最大値  /proc/sys/kernel/pid_max に達していた (proc(5) 参
              照)。

       EINVAL attr で指定された設定が不正である。

       EPERM  attr に指定されたスケジューリングポリシーとパラメーターを 設定する許可がない。

属性

       この節で使用されている用語の説明については、 attributes(7) を参照。

       ┌─────────────────┬───────────────┬─────────┐
       │インターフェース属性      │
       ├─────────────────┼───────────────┼─────────┤
       │pthread_create() │ Thread safety │ MT-Safe │
       └─────────────────┴───────────────┴─────────┘

準拠

       POSIX.1-2001, POSIX.1-2008.

注意

       pthread_create() が *thread で返すスレッド ID についての 詳しい情報は pthread_self(3) を参
       照のこと。  リアルタイムスケジューリングポリシーが使用されない限り、 pthread_create() の呼
       び出し後に、 どのスレッドが—呼び出したスレッドか新しいスレッドか— 次に実行されるかは決まっ
       ていない。

       スレッドは join 可能detached (切り離された状態) のどちらかに することができる。スレッド
       が join 可能な場合、別のスレッドが pthread_join(3)  を使って終了したスレッドを待ち、終了ス
       テータスを取得 することができる。終了した join 可能なスレッドは join された場合にのみ、 そ
       のスレッドの最後に残ったリソースが解放されシステムに戻される。 detached 状態のスレッドが終
       了すると、そのスレッドのリソースは自動的に  システムに戻される。detached  状態のスレッドを
       join して、その終了 ステータスを取得することはできない。スレッドを  detached  状態にするの
       は、 その終了ステータスをアプリケーションが気にする必要がないある種の デーモン (daemon) ス
       レッドでは有用である。  デフォルトでは、新しいスレッドは   join   可能な状態で作成される。
       (pthread_attr_setdetachstate(3)  を使って) attr でスレッドが detached 状態で作成されるよう
       に設定されていない限り、join 可能な状態で 作成される。

       Under the NPTL threading implementation, if the RLIMIT_STACK soft resource  limit  at  the
       time  the  program  started  has  any value other than "unlimited", then it determines the
       default stack size of new threads.  Using  pthread_attr_setstacksize(3),  the  stack  size
       attribute  can be explicitly set in the attr argument used to create a thread, in order to
       obtain a stack size other than the default.  If the 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:

              ┌─────────────┬────────────────────┐
              │ArchitectureDefault 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 │
              └─────────────┴────────────────────┘

バグ

       廃止予定の LinuxThreads 実装では、プロセス内の各スレッドは異なる プロセス ID  を持つ。これ
       は   POSIX   スレッドの規格に違反しており、   他の多くの標準非準拠の点の原因になっている。
       pthreads(7) を参照のこと。

       以下のプログラムは、 pthread_create() や pthreads API の他のいろいろな関数の使用例を示して
       いる。

       以下の実行例は、  NPTL スレッド実装が提供されているシステムでのもので、 スタックサイズがデ
       フォルト値の "stack size" リソース上限で指定される値 になる。

           $ ulimit -s
           8192            # The stack size limit is 8 MB (0x800000 bytes)
           $ ./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

       次の実行例では、プログラム内で、作成されるスレッドに対して   (pthread_attr_setstacksize(3)
       を使って1 MB のスタックサイズを明示的に設定している。

           $ ./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

   プログラムのソース

       #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) \
               do { errno = en; perror(msg); exit(EXIT_FAILURE); } while (0)

       #define handle_error(msg) \
               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\n",
                   tinfo->thread_num, &p, tinfo->argv_string);

           uargv = strdup(tinfo->argv_string);
           if (uargv == NULL)
               handle_error("strdup");

           for (char *p = uargv; *p != '\0'; p++)
               *p = toupper(*p);

           return uargv;
       }

       int
       main(int argc, char *argv[])
       {
           int s, opt, num_threads;
           pthread_attr_t attr;
           size_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 's':
                   stack_size = strtoul(optarg, NULL, 0);
                   break;

               default:
                   fprintf(stderr, "Usage: %s [-s stack-size] arg...\n",
                           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\n",
                       tinfo[tnum].thread_num, (char *) res);
               free(res);      /* Free memory allocated by thread */
           }

           free(tinfo);
           exit(EXIT_SUCCESS);
       }

関連項目

       getrlimit(2), pthread_attr_init(3), pthread_cancel(3), pthread_detach(3),
       pthread_equal(3), pthread_exit(3), pthread_getattr_np(3), pthread_join(3),
       pthread_self(3), pthread_setattr_default_np(3), pthreads(7)

この文書について

       この man ページは Linux man-pages プロジェクトのリリース 5.10 の一部である。プロジェクトの
       説明とバグ報告に関する情報は https://www.kernel.org/doc/man-pages/ に書かれている。