pthread_attr_init函数用法详解
pthread_attr_init函数简介
- 头文件包含
#include <pthread.h>
- 函数定义
int pthread_attr_init(pthread_attr_t * attr );
int pthread_attr_destroy(pthread_attr_t * attr );
- 编译链接选项
-pthread
pthread_attr_init函数常见使用错误
- 链接错误
undefined reference to `pthread_attr_init'
解决办法:添加链接选项
-pthread
- 编译错误
warning: implicit declaration of function ‘pthread_attr_init’ [-Wimplicit-function-declaration]
解决办法:包含头文件
#include <pthread.h>
pthread_attr_init函数详细描述
pthread_attr_init ()函数用默认属性值初始化attr指向的thread attributes对象。在此调用之后,可以使用各种相关函数设置对象的各个属性(请参见下面列出),然后可以在一个或多个创建线程的pthread_create (3)调用中使用该对象。
对已经初始化的thread attributes对象调用pthread_attr_init ()会导致未定义的行为。
当不再需要thread attributes对象时,应该使用pthread_attr_destroy ()函数销毁它。销毁thread attributes对象对使用该对象创建的线程没有影响。
一旦thread attributes对象被销毁,就可以使用pthread_attr_init ()对其进行重新初始化。对销毁的thread attributes对象的任何其他使用都有未定义的结果。
pthread_attr_init函数返回值
如果成功,这些函数返回0;错误时,它们返回一个非零错误号。
pthread_attr_init函数错误码
POSIX.1为Linux上的pthread_attr_init ();记录了一个 ENOMEM 错误,这些函数总是成功的(但是可移植的和将来可靠的应用程序仍然应该处理可能的错误返回)。
pthread_attr_init函数其他说明
pthread_attr_t类型应该被视为不透明的:除了通过pthreads函数之外,对对象的任何访问都是不可移植的,并且会产生未定义的结果。
pthread_attr_init函数使用举例
下面的程序可选地使用pthread_attr_init ()和各种相关函数来初始化用于创建单个线程的thread attributes对象。创建后,线程使用pthread_getattr_np (3)函数(非标准GNU扩展)检索线程的属性,然后显示这些属性。
如果程序不使用命令行参数运行,那么它将NULL作为pthread_create (3)的attr参数传递,以便使用默认属性创建线程。在带有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
当我们提供一个堆栈大小作为命令行参数时,程序初始化一个thread attributes对象,在该对象中设置各种属性,并在调用pthread_create (3)中传递一个指向该对象的指针,在linux/x86-32上使用NPTL线程实现运行该程序,我们将看到以下内容:
" ./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
Program source&
#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_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\en", 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\en", 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\en", 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\en", 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\en", 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\en", prefix, v);
s = pthread_attr_getstack(attr, &stkaddr, &v);
if (s != 0)
handle_error_en(s, "pthread_attr_getstack");
printf("%sStack address = %p\en", prefix, stkaddr);
printf("%sStack size = %#zx bytes\en", 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:\en");
display_pthread_attr(&gattr, "\et");
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\en", 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() */
}
评论区