名前

pthread_attr_init, pthread_attr_destroy - スレッド属性オブジェクトの初期化と破棄を行う

書式

#include <pthread.h>
int pthread_attr_init(pthread_attr_t *attr);
int pthread_attr_destroy(pthread_attr_t *attr);
-pthread でコンパイルしてリンクする。

説明

pthread_attr_init() 関数は attr が指すスレッド属性オブジェクト (thread attributes object) をデフォルトの属性値で初期化する。 この呼び出しの後、オブジェクトの各属性は (関連項目に載っている) 種々の 関数を使って設定することができ、このオブジェクトはスレッドの作成を行う pthread_create(3) の呼び出しにおいて使用することができる (一つの オブジェクトを複数の pthread_create(3) に渡してもよい)。
すでに初期化されているスレッド属性オブジェクトに対して pthread_attr_init() を呼び出した場合、 どのような動作になるかは不定である。
スレッド属性オブジェクトがもはや必要なくなった際には、 そのオブジェクトは pthread_attr_destroy() 関数を使って破棄すべきである。 スレッド属性オブジェクトを破棄しても、 そのオブジェクトを使って作成されたスレッドには影響はない。
いったん破棄したスレッド属性オブジェクトは、 pthread_attr_init() を使って再初期化することができる。 破棄したスレッド属性オブジェクトをこれ以外の用途で 使った場合の結果は不定である。

返り値

成功すると、これらの関数は 0 を返す。 エラーの場合、0 以外のエラー番号を返す。

エラー

POSIX.1 では pthread_attr_init() にはエラー ENOMEM が記載されている。 Linux では、これらの関数は常に成功する (ただし、移植性や将来も動作することを保証したいアプリケーションでは正のエラーの返り値を処理するようにすべきである)。

属性

この節で使用されている用語の説明については、 attributes(7) を参照。
インターフェース 属性
pthread_attr_init(), pthread_attr_destroy() Thread safety MT-Safe

準拠

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

注意

pthread_attr_t 型の内部構造は意識すべきではない。 pthreads 関数経由以外でのオブジェクトへのアクセスは移植性がなく、 どのような結果が得られるかも分からない。

下記のプログラムは、 pthread_attr_init() と種々の関連関数を使って、 スレッド属性オブジェクトの初期化を行い、 そのオブジェクトを使ってスレッドを一つ作成する。 作成されたスレッドは、作成後に pthread_getattr_np(3) 関数 (非標準の GNU 拡張) を使ってスレッドの属性を取得し、 取得した属性を表示する。
コマンドライン引数なしでプログラムを実行した場合、 pthread_create(3)attr 引数には NULL が渡される。 この場合、スレッドはデフォルトの属性で作成される。 このプログラムを NPTL スレッド実装が使われている Linux/x86-32 で 動作させると、以下のような出力が得られる。

$  ulimit -s       # No stack limit ==> default stack size is 2 MB
unlimited
$  ./a.out
Thread attributes:
        Detach state        = PTHREAD_CREATE_JOINABLE
        Scope               = PTHREAD_SCOPE_SYSTEM
        Inherit scheduler   = PTHREAD_INHERIT_SCHED
        Scheduling policy   = SCHED_OTHER
        Scheduling priority = 0
        Guard size          = 4096 bytes
        Stack address       = 0x40196000
        Stack size          = 0x201000 bytes

コマンドライン引数でスタックサイズが与えられた場合、 このプログラムは、スレッド属性オブジェクトを初期化し、 そのオブジェクトの各種属性を設定し、 pthread_create(3) の呼び出しでこのオブジェクトへのポインターを渡す。 このプログラムを NPTL スレッド実装が使われている Linux/x86-32 で 動作させると、以下のような出力が得られる。

$  ./a.out 0x3000000
posix_memalign() allocated at 0x40197000
Thread attributes:
        Detach state        = PTHREAD_CREATE_DETACHED
        Scope               = PTHREAD_SCOPE_SYSTEM
        Inherit scheduler   = PTHREAD_EXPLICIT_SCHED
        Scheduling policy   = SCHED_OTHER
        Scheduling priority = 0
        Guard size          = 0 bytes
        Stack address       = 0x40197000
        Stack size          = 0x3000000 bytes

プログラムのソース

#define _GNU_SOURCE     /* To get pthread_getattr_np() declaration */
#include <pthread.h>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <errno.h>
#define handle_error_en(en, msg) \ do { errno = en; perror(msg); exit(EXIT_FAILURE); } while (0)
static void display_pthread_attr(pthread_attr_t *attr, char *prefix) { int s, i; size_t v; void *stkaddr; struct sched_param sp;
s = pthread_attr_getdetachstate(attr, &i); if (s != 0) handle_error_en(s, "pthread_attr_getdetachstate"); printf("%sDetach state = %s\n", prefix, (i == PTHREAD_CREATE_DETACHED) ? "PTHREAD_CREATE_DETACHED" : (i == PTHREAD_CREATE_JOINABLE) ? "PTHREAD_CREATE_JOINABLE" : "???");
s = pthread_attr_getscope(attr, &i); if (s != 0) handle_error_en(s, "pthread_attr_getscope"); printf("%sScope = %s\n", prefix, (i == PTHREAD_SCOPE_SYSTEM) ? "PTHREAD_SCOPE_SYSTEM" : (i == PTHREAD_SCOPE_PROCESS) ? "PTHREAD_SCOPE_PROCESS" : "???");
s = pthread_attr_getinheritsched(attr, &i); if (s != 0) handle_error_en(s, "pthread_attr_getinheritsched"); printf("%sInherit scheduler = %s\n", prefix, (i == PTHREAD_INHERIT_SCHED) ? "PTHREAD_INHERIT_SCHED" : (i == PTHREAD_EXPLICIT_SCHED) ? "PTHREAD_EXPLICIT_SCHED" : "???");
s = pthread_attr_getschedpolicy(attr, &i); if (s != 0) handle_error_en(s, "pthread_attr_getschedpolicy"); printf("%sScheduling policy = %s\n", prefix, (i == SCHED_OTHER) ? "SCHED_OTHER" : (i == SCHED_FIFO) ? "SCHED_FIFO" : (i == SCHED_RR) ? "SCHED_RR" : "???");
s = pthread_attr_getschedparam(attr, &sp); if (s != 0) handle_error_en(s, "pthread_attr_getschedparam"); printf("%sScheduling priority = %d\n", prefix, sp.sched_priority);
s = pthread_attr_getguardsize(attr, &v); if (s != 0) handle_error_en(s, "pthread_attr_getguardsize"); printf("%sGuard size = %zu bytes\n", prefix, v);
s = pthread_attr_getstack(attr, &stkaddr, &v); if (s != 0) handle_error_en(s, "pthread_attr_getstack"); printf("%sStack address = %p\n", prefix, stkaddr); printf("%sStack size = %#zx bytes\n", prefix, v); }
static void * thread_start(void *arg) { int s; pthread_attr_t gattr;
/* pthread_getattr_np() is a non-standard GNU extension that retrieves the attributes of the thread specified in its first argument */
s = pthread_getattr_np(pthread_self(), &gattr); if (s != 0) handle_error_en(s, "pthread_getattr_np");
printf("Thread attributes:\n"); display_pthread_attr(&gattr, "\t");
exit(EXIT_SUCCESS); /* Terminate all threads */ }
int main(int argc, char *argv[]) { pthread_t thr; pthread_attr_t attr; pthread_attr_t *attrp; /* NULL or &attr */ int s;
attrp = NULL;
/* If a command-line argument was supplied, use it to set the stack-size attribute and set a few other thread attributes, and set attrp pointing to thread attributes object */
if (argc > 1) { size_t stack_size; void *sp;
attrp = &attr;
s = pthread_attr_init(&attr); if (s != 0) handle_error_en(s, "pthread_attr_init");
s = pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED); if (s != 0) handle_error_en(s, "pthread_attr_setdetachstate");
s = pthread_attr_setinheritsched(&attr, PTHREAD_EXPLICIT_SCHED); if (s != 0) handle_error_en(s, "pthread_attr_setinheritsched");
stack_size = strtoul(argv[1], NULL, 0);
s = posix_memalign(&sp, sysconf(_SC_PAGESIZE), stack_size); if (s != 0) handle_error_en(s, "posix_memalign");
printf("posix_memalign() allocated at %p\n", sp);
s = pthread_attr_setstack(&attr, sp, stack_size); if (s != 0) handle_error_en(s, "pthread_attr_setstack"); }
s = pthread_create(&thr, attrp, &thread_start, NULL); if (s != 0) handle_error_en(s, "pthread_create");
if (attrp != NULL) { s = pthread_attr_destroy(attrp); if (s != 0) handle_error_en(s, "pthread_attr_destroy"); }
pause(); /* Terminates when other thread calls exit() */ }

関連項目

pthread_attr_setaffinity_np(3), pthread_attr_setdetachstate(3), pthread_attr_setguardsize(3), pthread_attr_setinheritsched(3), pthread_attr_setschedparam(3), pthread_attr_setschedpolicy(3), pthread_attr_setscope(3), pthread_attr_setsigmask_np(3), pthread_attr_setstack(3), pthread_attr_setstackaddr(3), pthread_attr_setstacksize(3), pthread_create(3), pthread_getattr_np(3), pthread_setattr_default_np(3), pthreads(7)

この文書について

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