+.\" Copyright (c) 2008 Linux Foundation, written by Michael Kerrisk
+.\" <mtk.manpages@gmail.com>
+.\"
+.\" 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.
+.\"
+.\"*******************************************************************
+.\"
+.\" This file was generated with po4a. Translate the source file.
+.\"
+.\"*******************************************************************
+.TH PTHREAD_GETATTR_NP 3 2010\-09\-10 Linux "Linux Programmer's Manual"
+.SH 名前
+pthread_getattr_np \- 作成されたスレッドの属性を取得する
+.SH 書式
+.nf
+\fB#define _GNU_SOURCE\fP /* See feature_test_macros(7) */
+\fB#include <pthread.h>\fP
+
+\fBint pthread_getattr_np(pthread_t \fP\fIthread\fP\fB, pthread_attr_t *\fP\fIattr\fP\fB);\fP
+.sp
+\fI\-pthread\fP でコンパイルしてリンクする。
+.fi
+.SH 説明
+\fBpthread_getattr_np\fP() 関数は、
+\fIattr\fP が参照するスレッド属性オブジェクトを初期化し、
+そのオブジェクトに実行中のスレッド \fIthread\fP の実際の属性値を
+格納して返す。
+
+返される属性値は、\fBpthread_create\fP(3) でスレッドを作成する際に
+使われた\fIattr\fP オブジェクトで渡された属性値と異なる場合がある。
+特に、以下の属性は異なる場合がある。
+.IP * 2
+detach state. join 可能なスレッドは作成後に自分自身を
+切り離す (detach する) ことができるからである。
+.IP *
+スタックサイズ。
+スレッドの実装によって適切な境界に揃えられる可能があるためである。
+.IP *
+guard size.
+スレッドの実装によりページサイズの倍数に切り上げられたり、
+アプリケーションが自分でスタックを割り当てる場合には無視される
+(0 として扱われる) ことがあるからである。
+.PP
+さらに、スレッドを作成する際に使用されたスレッド属性オブジェクトで
+スタックアドレスが設定されていなかった場合、
+返されたスレッド属性オブジェクトではスレッドの実装がそのスレッドに
+割り当てた実際のスタックアドレスが報告される。
+
+\fBpthread_getattr_np\fP() が返したスレッド属性オブジェクトが
+必要なくなった際には、 \fBpthread_attr_destroy\fP(3) を使って
+そのオブジェクトを破棄すべきである。
+.SH 返り値
+成功すると、この関数は 0 を返す。
+エラーの場合、 0 以外のエラー番号を返す。
+.SH エラー
+.TP
+\fBENOMEM\fP
+.\" Can happen (but unlikely) while trying to allocate memory for cpuset
+メモリが十分になかった。
+.PP
+さらに、 \fIthread\fP がメインスレッドを参照している場合には、
+\fBpthread_getattr_np\fP() は内部で行われる様々な呼び出しでの
+エラーで失敗する可能性がある。
+\fI/proc/self/maps\fP がオープンできない場合には \fBfopen\fP(3)
+でエラーが発生し、リソース上限 \fBRLIMIT_STACK\fP が
+サポートされていない場合には \fBgetrlimit\fP(2) でエラーが発生する。
+.SH バージョン
+この関数は glibc バージョン 2.2.3 以降で利用できる。
+.SH 準拠
+この関数は非標準の GNU による拡張である。
+そのため、名前に "_np" (nonportable; 移植性がない) という接尾辞が
+付いている。
+.SH 例
+以下のプログラムは \fBpthread_getattr_np\fP() の使用例を示したものである。
+このプログラムは、スレッドを作成し、それから
+\fBpthread_getattr_np\fP() を使ってそのスレッドの属性 guard size、
+スタックアドレス、スタックサイズを取得し表示する。
+コマンドライン引き数での指定で、スレッドを作成する際に
+上記の属性にデフォルト値以外の値を設定することができる。
+下記のシェルのセッションはこのプログラムの使用例である。
+
+最初の実行例は、デフォルトの属性でスレッドが作成されている
+(x86\-32 システム上で実行)。
+
+.in +4n
+.nf
+$\fB ulimit \-s\fP # No stack limit ==> default stack size is 2MB
+unlimited
+$\fB ./a.out\fP
+Attributes of created thread:
+ Guard size = 4096 bytes
+ Stack address = 0x40196000 (EOS = 0x40397000)
+ Stack size = 0x201000 (2101248) bytes
+.fi
+.in
+
+次の実行例では、guard size が指定された場合、
+guard size はシステムのページサイズの倍数に切り上げられることが分かる
+(x86\-32 ではシステムのページサイズは 4096 バイトである)。
+
+.in +4n
+.nf
+$\fB ./a.out \-g 4097\fP
+Thread attributes object after initializations:
+ Guard size = 4097 bytes
+ Stack address = (nil)
+ Stack size = 0x0 (0) bytes
+
+Attributes of created thread:
+ Guard size = 8192 bytes
+ Stack address = 0x40196000 (EOS = 0x40397000)
+ Stack size = 0x201000 (2101248) bytes
+.fi
+.in
+
+.\".in +4n
+.\".nf
+.\"$ ./a.out \-s 0x8000
+.\"Thread attributes object after initializations:
+.\" Guard size = 4096 bytes
+.\" Stack address = 0xffff8000 (EOS = (nil))
+.\" Stack size = 0x8000 (32768) bytes
+.\"
+.\"Attributes of created thread:
+.\" Guard size = 4096 bytes
+.\" Stack address = 0x4001e000 (EOS = 0x40026000)
+.\" Stack size = 0x8000 (32768) bytes
+.\".fi
+.\".in
+最後の実行例では、プログラムでスレッド用のスタックを手動で割り当てている。
+この場合には、guard size 属性は無視される。
+
+.in +4n
+.nf
+$\fB ./a.out \-g 4096 \-s 0x8000 \-a\fP
+Allocated thread stack at 0x804d000
+
+Thread attributes object after initializations:
+ Guard size = 4096 bytes
+ Stack address = 0x804d000 (EOS = 0x8055000)
+ Stack size = 0x8000 (32768) bytes
+
+Attributes of created thread:
+ Guard size = 0 bytes
+ Stack address = 0x804d000 (EOS = 0x8055000)
+ Stack size = 0x8000 (32768) bytes
+.fi
+.in
+.SS プログラムのソース
+\&
+.nf
+#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) \e
+ do { errno = en; perror(msg); exit(EXIT_FAILURE); } while (0)
+
+static void
+display_stack_related_attributes(pthread_attr_t *attr, char *prefix)
+{
+ int s;
+ size_t stack_size, guard_size;
+ void *stack_addr;
+
+ s = pthread_attr_getguardsize(attr, &guard_size);
+ if (s != 0)
+ handle_error_en(s, "pthread_attr_getguardsize");
+ printf("%sGuard size = %d bytes\en", prefix, guard_size);
+
+ s = pthread_attr_getstack(attr, &stack_addr, &stack_size);
+ if (s != 0)
+ handle_error_en(s, "pthread_attr_getstack");
+ printf("%sStack address = %p", prefix, stack_addr);
+ if (stack_size > 0)
+ printf(" (EOS = %p)", (char *) stack_addr + stack_size);
+ printf("\en");
+ printf("%sStack size = 0x%x (%d) bytes\en",
+ prefix, stack_size, stack_size);
+}
+
+static void
+display_thread_attributes(pthread_t thread, char *prefix)
+{
+ int s;
+ pthread_attr_t attr;
+
+ s = pthread_getattr_np(thread, &attr);
+ if (s != 0)
+ handle_error_en(s, "pthread_getattr_np");
+
+ display_stack_related_attributes(&attr, prefix);
+
+ s = pthread_attr_destroy(&attr);
+ if (s != 0)
+ handle_error_en(s, "pthread_attr_destroy");
+}
+
+static void * /* Start function for thread we create */
+thread_start(void *arg)
+{
+ printf("Attributes of created thread:\en");
+ display_thread_attributes(pthread_self(), "\et");
+
+ exit(EXIT_SUCCESS); /* Terminate all threads */
+}
+
+static void
+usage(char *pname, char *msg)
+{
+ if (msg != NULL)
+ fputs(msg, stderr);
+ fprintf(stderr, "Usage: %s [\-s stack\-size [\-a]]"
+ " [\-g guard\-size]\en", pname);
+ fprintf(stderr, "\et\et\-a means program should allocate stack\en");
+ exit(EXIT_FAILURE);
+}
+
+static pthread_attr_t * /* Get thread attributes from command line */
+get_thread_attributes_from_cl(int argc, char *argv[],
+ pthread_attr_t *attrp)
+{
+ int s, opt, allocate_stack;
+ long stack_size, guard_size;
+ void *stack_addr;
+ pthread_attr_t *ret_attrp = NULL; /* Set to attrp if we initialize
+ a thread attributes object */
+ allocate_stack = 0;
+ stack_size = \-1;
+ guard_size = \-1;
+
+ while ((opt = getopt(argc, argv, "ag:s:")) != \-1) {
+ switch (opt) {
+ case \(aqa\(aq: allocate_stack = 1; break;
+ case \(aqg\(aq: guard_size = strtoul(optarg, NULL, 0); break;
+ case \(aqs\(aq: stack_size = strtoul(optarg, NULL, 0); break;
+ default: usage(argv[0], NULL);
+ }
+ }
+
+ if (allocate_stack && stack_size == \-1)
+ usage(argv[0], "Specifying \-a without \-s makes no sense\en");
+
+ if (argc > optind)
+ usage(argv[0], "Extraneous command\-line arguments\en");
+
+ if (stack_size >= 0 || guard_size > 0) {
+ ret_attrp = attrp;
+
+ s = pthread_attr_init(attrp);
+ if (s != 0)
+ handle_error_en(s, "pthread_attr_init");
+ }
+
+ if (stack_size >= 0) {
+ if (!allocate_stack) {
+ s = pthread_attr_setstacksize(attrp, stack_size);
+ if (s != 0)
+ handle_error_en(s, "pthread_attr_setstacksize");
+ } else {
+ s = posix_memalign(&stack_addr, sysconf(_SC_PAGESIZE),
+ stack_size);
+ if (s != 0)
+ handle_error_en(s, "posix_memalign");
+ printf("Allocated thread stack at %p\en\en", stack_addr);
+
+ s = pthread_attr_setstack(attrp, stack_addr, stack_size);
+ if (s != 0)
+ handle_error_en(s, "pthread_attr_setstacksize");
+ }
+ }
+
+ if (guard_size >= 0) {
+ s = pthread_attr_setguardsize(attrp, guard_size);
+ if (s != 0)
+ handle_error_en(s, "pthread_attr_setstacksize");
+ }
+
+ return ret_attrp;
+}
+
+int
+main(int argc, char *argv[])
+{
+ int s;
+ pthread_t thr;
+ pthread_attr_t attr;
+ pthread_attr_t *attrp = NULL; /* Set to &attr if we initialize
+ a thread attributes object */
+
+ attrp = get_thread_attributes_from_cl(argc, argv, &attr);
+
+ if (attrp != NULL) {
+ printf("Thread attributes object after initializations:\en");
+ display_stack_related_attributes(attrp, "\et");
+ printf("\en");
+ }
+
+ 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() */
+}
+.fi
+.SH 関連項目
+\fBpthread_attr_getaffinity_np\fP(3), \fBpthread_attr_getdetachstate\fP(3),
+\fBpthread_attr_getguardsize\fP(3), \fBpthread_attr_getinheritsched\fP(3),
+\fBpthread_attr_getschedparam\fP(3), \fBpthread_attr_getschedpolicy\fP(3),
+\fBpthread_attr_getscope\fP(3), \fBpthread_attr_getstack\fP(3),
+\fBpthread_attr_getstackaddr\fP(3), \fBpthread_attr_getstacksize\fP(3),
+\fBpthread_attr_init\fP(3), \fBpthread_create\fP(3), \fBpthreads\fP(7)
+.SH この文書について
+この man ページは Linux \fIman\-pages\fP プロジェクトのリリース 3.40 の一部
+である。プロジェクトの説明とバグ報告に関する情報は
+http://www.kernel.org/doc/man\-pages/ に書かれている。