pthread_attr_init 重复使用将会造成无法预知的错误

pthread_attr_init int pthread_attr_destroy 是对线程属性创建和删除的一对函数。

这里的线程属性是指pthread_create里的第二个参数。通常这个参数是NULL, 即默认状态。如果想要定制一些有别于默认值的属性,就需要用pthread_attr_init 创建一个独立的属性对象,然后再对其进行修改。属性对象的参数结构如下:
typedef struct

{

​ int detachstate; //线程的分离状态

​ int schedpolicy; //线程调度策略

​ structsched_param schedparam; //线程的调度参数

​ int inheritsched; //线程的继承性

​ int scope; //线程的作用域

​ size_t guardsize; //线程栈末尾的警戒缓冲区大小

​ int stackaddr_set;

​ void\ stackaddr;//线程栈的位置

​ size_t stacksize; //线程栈的大小

}pthread_attr_t;
linux手册中对pthread_attr_init 的描述如下:

DESCRIPTION         top

       The pthread_attr_init() function initializes the thread
       attributes object pointed to by attr with default attribute
       values.  After this call, individual attributes of the object can
       be set using various related functions (listed under SEE ALSO),
       and then the object can be used in one or more pthread_create(3)
       calls that create threads.

       Calling pthread_attr_init() on a thread attributes object that
       has already been initialized results in undefined behavior.

       When a thread attributes object is no longer required, it should
       be destroyed using the pthread_attr_destroy() function.
       Destroying a thread attributes object has no effect on threads
       that were created using that object.

       Once a thread attributes object has been destroyed, it can be
       reinitialized using pthread_attr_init().  Any other use of a
       destroyed thread attributes object has undefined results.从中可以看出


这里面提到了2处无法预知错误,需要特别注意:
1.对一个已经创建好的属性对象重复使用pthread_attr_init 会造成无法预知的后果。

2.使用已经销毁的属性对象也会造成未知后果。

一些思考:
1.线程创建失败,仍然需要销毁属性对象吗? --应该是需要的,一个属性对象可以用于多个线程的创建,属性对象销毁也不影响已创建的线程,可以认为属性对象和线程是两回事。
从linux给的示例代码中也可以看到,不管pthread_create有没有成功,后面都执行了对属性对象的销毁。

2.属性对象一定要销毁吗?--应该需要,既然定义了这个函数,就应该在不需要时销毁它,应该是占用了内存空间的。
3.如果不需要修改属性,还要创建属性对象吗? --应该不用。刚创建好的属性对象是默认值,和pthread_create第二参数为NULL是一样的。创建好的属性对象需要通过set函数修改,如线程分离状态、调度策略等,如pthread_attr_setdetachstate 或 pthread_attr_setschedpolicy。还可以通过 pthread_getattr_np读取线程属性。

下面是示例代码,不重要的部分用“...”隐藏了,完整版可查看  在linux pthread_attr_init(3) - Linux manual page 

int
       main(int argc, char *argv[])
       {
           int s, opt, num_threads;
           pthread_attr_t attr;
           ssize_t stack_size;
           void *res;

        ...
           /* Initialize thread creation attributes. */

           s = pthread_attr_init(&attr);
           if (s != 0)
               handle_error_en(s, "pthread_attr_init");

        ...

           /* Create one thread for each command-line argument. */

           for (int tnum = 0; tnum < num_threads; tnum++) {
               tinfo[tnum].thread_num = tnum + 1;
               tinfo[tnum].argv_string = argv[optind + tnum];

               /* The pthread_create() call stores the thread ID into
                  corresponding element of tinfo[]. */

               s = pthread_create(&tinfo[tnum].thread_id, &attr,
                                  &thread_start, &tinfo[tnum]);
               if (s != 0)
                   handle_error_en(s, "pthread_create");
           }

           /* Destroy the thread attributes object, since it is no
              longer needed. */

           s = pthread_attr_destroy(&attr);
           if (s != 0)
               handle_error_en(s, "pthread_attr_destroy");

         ...
           exit(EXIT_SUCCESS);
       }
 

其它参考资料:

pthread_attr_setdetachstate(3)
pthread_attr_setschedpolicy(3)
pthread_getattr_np(3)
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值