侧边栏壁纸
博主头像
noerror

虚灵不寐,众理具而万事出。

  • 累计撰写 239 篇文章
  • 累计创建 9 个标签
  • 累计收到 2 条评论
标签搜索

目 录CONTENT

文章目录

pthread_attr_init函数用法详解

noerror
2022-10-04 / 0 评论 / 0 点赞 / 46 阅读 / 1,529 字 / 正在检测是否收录...

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() */
}
0

评论区