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/
に書かれている。