lienhua34
2014-11-09

1 线程属性概括

POSIX 线程的主要属性包括 scope 属性、detach 属性、堆栈地址、堆栈大小、优先级。在头文件 pthread.h 中定义了结构体pthread_attr_t 来记录线程的属性。

在创建线程的函数pthread_create 的第二个参数 attr 就是一个pthread_attr_t结构体的指针,通过该参数,我们可以控制新创建的线程的属性。如果 atrr参数为 NULL,表示创建一个默认属性的新线程。

pthread_attr_t 结构体对于应用程序来说是透明的,也就是说应用程序不需要关心各个属性在该结构体中的实现字段。头文件 pthread.h 提供了操作这些属性的函数。pthread_attr_init 函数和pthread_attr_destroy函数分别用于线程属性pthread_attr_t 结构体的初始化和摧毁。

#include <pthread.h>

int pthread_attr_init(pthread_attr_t *attr);

int pthread_attr_destroy(pthread_attr_t *attr);

返回值:若成功则返回0,否则返回错误编号

在调用pthread_create 函数之前,调用pthread_attr_init 函数初始化pthread_attr_t 结构体为操作系统支持的线程所有属性默认值。在调用pthread_create 函数创建线程之后,要调用pthread_attr_destroy 函数来摧毁pthread_attr_t 结构体,因为某些线程属性对象可能分配了动态内存空间。

下面简单说明一下几个主要的线程属性及其操作函数。

1.1 detach 属性

detach属性,也称为分离状态,表示新线程是否与进程中其它线程脱离同步。如果设置为PTHREAD_CREATE_DETACHED, 此时新线程将以分离状态启动, 且新线程在退出时自行释放所占用的资源。如果设置为PTHREAD_CREATE_JOINABLE,新线程在退出后,需要调用pthread_join来获取该线程的退出状态,并释放该线程所占有的资源。缺省值为PTHREAD_CREATE_JOINABLE。该属性的操作函数为,详细说明请参考http://pubs.opengroup.org

#include <pthread.h>

int pthread_attr_getdetachstate(const pthread_attr_t *restrict attr, int *detachstate);

int pthread_attr_setdetachstate(pthread_attr_t *restrict attr, int detachstate);

两个函数返回值:若成功则返回0,否则返回错误编号

1.2 调度策略属性

新线程的调度策略包括SCHED_OTHER(正常、非实时)、SCHED_RR(实时、轮转法)和SCHED_FIFO(实时、先入先出),缺省为SCHED_OTHER,后两种调度策略仅对超级用户有效。调度策略属性的操作函数为,详细说明请参考http://pubs.opengroup.org

#include <pthread.h>

int pthread_attr_setschedpolicy(pthread_attr_t *attr, int policy);

int pthread_attr_getschedpolicy(const pthread_attr_t *attr, int *policy);

1.3 优先级属性

该属性在实现时通过 struct sched_param 结构中的sched_priority 整型变量来表示。这个属性仅当调度策略为实时(即SCHED_RR 或SCHED_FIFO)时才有效,并可以在运行时通过pthread_setschedparam() 函数来改变,缺省为 0. 系统支持的最大和最小的优先级值可以用函数sched_get_priority_max和sched_get_priority_min 得到。详细说明请参考http://pubs.opengroup.org

#include <pthread.h>

int pthread_attr_setschedparam(pthread_attr_t *attr,const struct sched_param *param);

int pthread_attr_getschedparam(const pthread_attr_t *attr, struct sched_param *param);

1.4 scope 属性

scope 属性表示线程间竞争 CPU 的范围,也就是说线程优先级的有效范围。其有效值有两个: PTHREAD_SCOPE_SYSTEM 和PTHREAD_SCOPE_PROCESS,前者表示与系统中所有线程一起竞争 CPU 时间,后者表示仅与同进程中的线程竞争 CPU 时间。详细说明请参考http://pubs.opengroup.org

#include <pthread.h>

int pthread_attr_setscope(pthread_attr_t *attr, int contentionscope);

int pthread_attr_getscope(const pthread_attr_t *attr, int *contentionscope);

2 线程分离状态例子

要创建一个分离状态的新线程,我们调用pthread_attr_setdetachstate函数来设置pthread_create 函数的 attr 参数的 detachstate 属性为PTHREAD_CREATE_DETACHED,或者在创建线程之后,调用pthread_detach 函数来设置一个线程为分离状态。pthread_detach 函数的声明如下,

#include <pthread.h>

int pthread_detach(pthread_t tid);

返回值:若成功则返回0,否则返回错误编号

如果线程处于分离状态,则线程的底层存储资源在线程终止时立即被收回。对于处于分离状态的线程,调用pthread_join 函数会返回错误。下面我们来看一个分离状态的例子,

#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <pthread.h> void *
my_thread(void *arg)
{
printf("in new thread. \n");
sleep();
printf("out new thread.\n");
return ((void *));
} int
main(void)
{
int err;
pthread_t tid;
void *tret;
pthread_attr_t attr; err = pthread_attr_init(&attr);
if (err != ) {
printf("pthread_attr init error: %s\n", strerror(err));
exit(-);
} err = pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED);
if (err != ) {
printf("pthread_attr_setdetachstate error: %s\n", strerror(err));
exit(-);
} err = pthread_create(&tid, &attr, my_thread, NULL);
if ( err != ) {
printf("can't create thread: %s\n", strerror(err));
exit(-);
}
err = pthread_join(tid, &tret);
if (err != ) {
printf("pthread_join error: %s\n", strerror(err));
exit(-);
}
printf("new thread return value: %d\n", (int)tret);
pthread_attr_destroy(&attr); exit();
}

上面的程序中,设置了调用pthread_attr_setdetachstate 函数将传递给pthread_create 函数的 attr 参数的 detachstate 属性设置为PTHREAD_CREATE_DETACHED。则pthread_create 函数将以分离状态创建新线程, 然后对新线程调用pthread_join 函数。编译该程序,生成并执行可执行文件pthread_detach_demo,

lienhua34:demo$ gcc -o pthread_detach_demo -pthread pthread_detach_demo.c
lienhua34:demo$ ./pthread_detach_demo
in new thread.
pthread_join error: Invalid argument

从上面的运行结果,我们可以看到对于分离状态的线程,调用pthread_join函数时报错了。如果将上面程序中调用pthread_attr_setdetachstate 的一行代码注释掉,然后重现编译该程序,生成并执行可执行文件pthread_detach_demo,

lienhua34:demo$ gcc -o pthread_detach_demo -pthread pthread_detach_demo.c
lienhua34:demo$ ./pthread_detach_demo
in new thread.
out new thread.
new thread return value:

从上面运行结果可以看到,对于非分离状态的线程,pthread_join 函数能够正常获取该线程的返回值。

(done)

UNIX环境编程学习笔记(27)——多线程编程(二):控制线程属性的更多相关文章

  1. 孙鑫VC学习笔记:多线程编程

    孙鑫VC学习笔记:多线程编程 SkySeraph Dec 11st 2010  HQU Email:zgzhaobo@gmail.com    QQ:452728574 Latest Modified ...

  2. Python Web学习笔记之多线程编程

    本次给大家介绍Python的多线程编程,标题如下: Python多线程简介 Python多线程之threading模块 Python多线程之Lock线程锁 Python多线程之Python的GIL锁 ...

  3. 并发编程学习笔记之可见性&过期数据(二)

    想要使用多线程编程,有一个很重要的前提,那就是必须保证操纵的是线程安全的类. 那么如何构建线程安全的类呢? 1. 使用同步来避免多个线程在同一时间访问同一数据. 2. 正确的共享和安全的发布对象,使多 ...

  4. 网络编程学习笔记:Socket编程

    文的主要内容如下: 1.网络中进程之间如何通信? 2.Socket是什么? 3.socket的基本操作 3.1.socket()函数 3.2.bind()函数 3.3.listen().connect ...

  5. python核心编程学习记录之多线程编程

  6. Java学习笔记:多线程(二)

    与线程生命周期相关的方法: sleep 调用sleep方法会进入计时等待状态,等待时间到了,进入就绪状态. yield 调用yield方法会让别的线程执行,但是不确保真正让出.较少使用,官方注释都说 ...

  7. apue学习笔记(第十二章 线程控制)

    本章将讲解控制线程行为方面的详细内容,而前面的章节中使用的都是它们的默认行为 线程属性 pthread接口允许我们通过设置每个对象关联的不同属性来细调线程和同步对象的行为.管理这些属性的函数都遵循相同 ...

  8. 多线程编程学习笔记——编写一个异步的HTTP服务器和客户端

    接上文 多线程编程学习笔记——使用异步IO 二.   编写一个异步的HTTP服务器和客户端 本节展示了如何编写一个简单的异步HTTP服务器. 1.程序代码如下. using System; using ...

  9. 多线程编程学习笔记——async和await(一)

    接上文 多线程编程学习笔记——任务并行库(一) 接上文 多线程编程学习笔记——任务并行库(二) 接上文 多线程编程学习笔记——任务并行库(三) 接上文 多线程编程学习笔记——任务并行库(四) 通过前面 ...

  10. 多线程编程学习笔记——async和await(二)

    接上文 多线程编程学习笔记——async和await(一) 三.   对连续的异步任务使用await操作符 本示例学习如何阅读有多个await方法方法时,程序的实际流程是怎么样的,理解await的异步 ...

随机推荐

  1. iOS - UITableView加载网络图片 cell适应图片高度

    使用xib创建自定制cell   显示图片   创建一个继承UITableViewCell的类   勾选xib 如下是xib创建图 xib 向.h拖拽一个关联线 .h .m 2.代码创建(使用三方适配 ...

  2. [转]ORA-01555错误总结(一)

    原文地址:http://blog.csdn.net/sh231708/article/details/52935695 这篇文章算是undo相关问题总结的补充,因为ORA-01555错误与undo有着 ...

  3. bzoj1103【POI2007】大都市meg

    1103: [POI2007]大都市meg Time Limit: 10 Sec  Memory Limit: 162 MB Submit: 1544  Solved: 776 [Submit][St ...

  4. thinkphp继承高级model后的乐观锁运用(测试中)

    <?php class IndexAction extends Action { private $d_user; private $user; private $arr; public fun ...

  5. [Linux]Shell的运算符和特殊变量

    说起Shell脚本,免不了用变量.特别是对于这种一堆符号表示变量的语言来说,你不了解一下相关变量的本意,根本无从下手.譬如写个循环遍历,$#就起了好大作用.所以还是有必要记录一下,也是对学习的一个笔记 ...

  6. windows 下 MySql5.6主从复制

    说明: 1.MySql 版本5.6 2.本例中使用的主从服务器ip分别为:192.168.120.211:192.168.120.209 一.配置master服务器 1.配置 在my.ini中[mys ...

  7. springcloud服务已经关但是Eureka还是显示up

    该状态持续很久,访问该服务也返回错误,但在注册中心界面,该服务却一直存在,且为UP状态,并且在大约十分钟后,出现一行红色大字:EMERGENCY! EUREKA MAY BE INCORRECTLY ...

  8. PCL点云分割(2)

    关于点云的分割算是我想做的机械臂抓取中十分重要的俄一部分,所以首先学习如果使用点云库处理我用kinect获取的点云的数据,本例程也是我自己慢慢修改程序并结合官方API 的解说实现的,其中有很多细节如果 ...

  9. Linux系统下邮件服务器的搭建(Postfix+Dovecot)

    对于网站来说,发送各种例如注册通知的邮件是很基本的一个需求,之前我一直用的是腾讯的企业邮箱,感觉挺方便的,直接可以绑定QQ邮箱接收邮件,网站配置一下SMTP也就可以发出邮件. 但是在前几天由于有重要信 ...

  10. Android开发 listitem中采用倒计时

    采用单个倒计时控件会紊乱,故采用在activity中倒计时异步刷新通知的方式全局更新数据源  notifyDataSetChanged 效果如下: 大致思路: 若出现刷新倒计时有的显示有的不显示的情况 ...