-
-
-
- #define _GNU_SOURCE /* 引入 pthread_getattr_np() 声明 */
-
#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_getinheritschedw(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 = %d 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 = 0x%x bytes\n", prefix, v);
-
}
-
-
static void *
-
thread_start(void *arg)
-
{
-
int s;
-
pthread_attr_t gattr;
-
-
/* pthread_getattr_np() 一个非标准的 GNU 扩展,
-
它用于取得其第一个参数引用的线程的属性。*/
-
-
s = pthread_getattr_np(pthread_self(), &gattr);//pthread_self()获得calling线程的线程id
-
if (s != 0)
-
handle_error_en(s, "pthread_getattr_np");
-
-
printf("Thread attributes:\n");
-
display_pthread_attr(&gattr, "\t");
-
-
exit(EXIT_SUCCESS); /* 终止所有线程 */
-
}
-
-
int
-
main(int argc, char *argv[])
-
{
-
pthread_t thr;
-
pthread_attr_t attr;
-
pthread_attr_t *attrp; /* NULL or &attr */
-
int s;
-
-
attrp = NULL;
-
-
/* 如果命令行参数提供了,使用它来设置线尺寸属性,
-
以及一些其它属性,并设置 attrp 指向这个线程属性对象 */
-
-
printf("argc=%d\n",argc);
-
-
if (argc > 1) {
-
int 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);//convert a string to an unsigned long integer
-
-
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(); /* 当其它线程调用 exit() 时终止 */
-
return 0;
-
}
//pthread_attr_init()的man手册实例
//$ ./a.out
或
//$ ./a.out 0x3000000