pthread_attr_t 的缺省属性值 
属性 结果
scope PTHREAD_SCOPE_PROCESS 新线程与进程中的其他线程发生竞争。
detachstate PTHREAD_CREATE_JOINABLE 线程退出后,保留完成状态和线程 ID
stackaddr NULL 新线程具有系统分配的栈地址。
stacksize 1M 新线程具有系统定义的栈大小。
priority 0 新线程的优先级为0。
inheritsched PTHREAD_EXPLICIT_SCHED 新线程不继承父线程调度优先级。
schedpolicy SCHED_OTHER 新线程对同步对象争用使用 Solaris 定义的固定优先级。线程将一直运行,直到被抢占或者直到线程阻塞或停止为止。
guardsize PAGESIZE(4M) 新线程具有系统定义的栈溢出保护区大小
1、初始化一个线程对象的属性
int pthread_attr_init(pthread_attr_t *attr);
返回值:若是成功返回0,否则返回错误的编号
形 参: attr 指向一个线程属性的指针
说 明:Posix线程中的线程属性pthread_attr_t主要包括scope属性、detach属性、堆栈地址、堆栈大小、优先级。
pthread_attr_init实现时为属性对象分配了动态内存空间。
线程属性结构如下:
typedef struct
{
int detachstate; 线程的分离状态
int schedpolicy; 线程调度策略
struct sched_param schedparam; 线程的调度参数
int inheritsched; 线程的继承性
int scope; 线程的作用域
size_t guardsize; 线程栈末尾的警戒缓冲区大小
int stackaddr_set;
void* stackaddr; 线程栈的位置
size_t stacksize; 线程栈的大小
}pthread_attr_t;

2、销毁一个线程属性对象
int pthread_attr_destroy(pthread_attr_t *attr);
返回值:若是成功返回0,否则返回错误的编号
形 参:attr 指向一个线程属性的指针
说 明:如果pthread_attr_init实现时为属性对象分配了动态内存空间,pthread_attr_destroy将会释放该内存空间。
经pthread_attr_destroy去除初始化之后的pthread_attr_t结构被pthread_create函数调用,将会导致其返回错误。

3、获取线程分离状态属性.
int pthread_attr_getdetachstate(pthread_attr_t *attr, int *detachstate);
返回值:若是成功返回0,否则返回错误的编号
形 参: attr 指向一个线程属性的指针
detachstate 保存返回的分离状态属性,有两个取值:
  • PTHREAD_CREATE_DETACHED(分离)
  • PTHREAD_CREATE_JOINABLE(非分离)
说 明:获取线程分离状态属性

4、修改线程分离状态属性
int pthread_attr_setdetachstate(pthread_attr_t *attr, int detachstate);
     如果对现有的某个线程的终止状态不感兴趣的话,可以使用pthread_detach函数让操作系统在线程退出时收回它所占有的资源。如果在创建线程之前就知道不需要了解线程的终止状态,则可以修改pthread_attr_t结构中的detachstate线程属性,让线程以分离状态启动。其中pthread_detach函数时在线程创建之后设置分离属性的。
返回值:若是成功返回0,否则返回错误的编号
形 参:attr 指向一个线程属性的指针
detachstat 有两个取值:
  • PTHREAD_CREATE_DETACHED(分离)
  • PTHREAD_CREATE_JOINABLE(非分离)
说 明:所有的Pthreads系统都支持detachstate属性,该属性的值可以是PTHREAD_CREATE_DETACHED(分离)或PTHREAD_CREATE_JOINABLE(非分离)。默认的,线程被创建为非分离,即意味着由pthread_create创建的该线程ID能被用来与线程连接并获得它的返回值,或取消它。

5、获取线程的堆栈信息(栈地址和栈大小)
int pthread_attr_getstack(pthread_attr_t *attr, void **stackaddr, size_t *stacksize);
返回值:若是成功返回0,否则返回错误的编号
形 参:attr 指向一个线程属性的指针
stackaddr 返回获取的栈地址
stacksize 返回获取的栈大小
说 明:获取线程的堆栈地址和大小


6、设置线程的堆栈信息(栈地址和栈大小)
int pthread_attr_setstack(pthread_attr_t *attr, void *stackaddr, size_t stacksize);
返回值:若是成功返回0,否则返回错误的编号
形 参:attr 指向一个线程属性的指针
stackaddr 线程的堆栈地址(低位地址):应该是可移植的,对齐页边距的可以用posix_memalign来进行获取。如果将 stackaddr 设置为非空值,而不是缺省的 NULL,则系统将在该地址初始化栈,假设大小为 stacksize
stacksize 线程的堆栈大小:应该是页大小的整数倍
说 明:设置堆栈区,将导致pthread_attr_setguardsize失效。

试用场合:对进程来说,虚拟地址空间的大小是固定的,进程中只有一个栈,所以它的大小通常不是问题。但对线程来说,同样大小的虚拟地址空间必须被所有的线程栈共享。如果应用程序使用了太多的线程,致使线程栈的累计大小超过了可用的虚拟地址空间,这时就需要减少线程默认的栈大小。另一方面,如果线程调用的函数分配了大量的自动变量或者调用的函数涉及很深的栈帧,那么这时需要的栈的大小可能要比默认的大。

注意:stackaddr  线程属性被定义为栈的内存单元的最低地址,但这并不是必然是栈的开始位置。对于某些处理器结构来说,栈是从高地址向低地址方向伸展的,那么stackaddr 线程属性就是栈的结尾而不是开始位置。
7、获取线程堆栈地址
int pthread_attr_getstackaddr(pthread_attr_t *attr, void **stackaddr);
返回值:若是成功返回0,否则返回错误的编号
形 参:attr 指向一个线程属性的指针
stackaddr 返回获取的栈地址
说 明:函数已过时,一般用pthread_attr_getstack来代替


8、设置线程堆栈地址
int pthread_attr_setstackaddr(pthread_attr_t *attr, void *stackaddr);
返回值:若是成功返回0,否则返回错误的编号
形 参:attr 指向一个线程属性的指针
stackaddr 设置线程堆栈地址
说 明:函数已过时,一般用pthread_attr_setstack来代替。


9、获取线程堆栈大小
int pthread_attr_getstacksize(pthread_attr_t *attr, size_t *stacksize);
返回值:若是成功返回0,否则返回错误的编号
形 参:attr 指向一个线程属性的指针
stacksize 返回线程的堆栈大小
说 明:获取线程堆栈大小。设置堆栈大小不是可移植的。Pthreads定义PTHREAD_STACK_MIN标志,指定每个线程要求的最小栈大小,包含#include <limits.h>后可以通过打印其值查看。命令:#ulimit -s或者#ulimit -a其中stack size项表示堆栈大小。#ulimit -s value用来重新设置stack大小。默认为8M,最小16384字节
注意:通常,线程栈是从页边界开始的。任何指定的大小都被向上舍入到下一个页边界。不具备访问权限的页将被附加到栈的溢出端。大多数栈溢出都会导致将 SIGSEGV 信号发送到违例线程(注意可以参考《UNIX环境高级编程——存储映射I/O(mmap函数)》)。将直接使用调用方分配的线程栈,而不进行修改。指定栈时,还应用 PTHREAD_CREATE_JOINABLE 创建线程。在该线程的 pthread_join调用返回之前,不会释放该栈。在该线程终止之前,不会释放该线程的栈。一般情况下,不需要为线程分配栈空间。系统会为每个线程的栈分配 1 MB(对于 32 位系统)或 2 MB(对于 64 位系统)的虚拟内存,而不保留任何交换空间。系统将使用 mmap() 的 MAP_NORESERVE 选项来进行分配。极少数情况下需要指定栈和/或栈大小。甚至专家也很难了解是否指定了正确的大小。

10、设置线程堆栈大小
int pthread_attr_setstacksize(pthread_attr_t *attr, size_t stacksize);
返回值:若是成功返回0,否则返回错误的编号
形 参:attr 指向一个线程属性的指针
stacksize 线程的堆栈大小(以字节为单位):应该是页大小的整数倍。(以字节为单位)。stacksize不应小于系统定义的最小栈大小。stacksize包含新线程使用的栈的字节数。如果 stacksize为零,则使用缺省大小。在大多数情况下,零值最适合。

11、获取线程的栈溢出保护区大小
int pthread_attr_getguardsize(pthread_attr_t *attr, size_t *guardsize);
返回值:若是成功返回0,否则返回错误的编号
形 参: attr 指向一个线程属性的指针
guardsize 返回获取的栈保护区大小
说 明:获取线程的栈保护区大小。 出于以下两个原因,为应用程序提供了 guardsize 属性:
  • 溢出保护可能会导致系统资源浪费。如果应用程序创建大量线程,并且已知这些线程永远不会溢出其栈,则可以关闭溢出保护区。通过关闭溢出保护区,可以节省系统资源。
  • 线程在栈上分配大型数据结构时,可能需要较大的溢出保护区来检测栈溢出。

guardsize 参数提供了对栈指针溢出的保护。如果创建线程的栈时使用了保护功能,则实现会在栈的溢出端分配额外内存。此额外内存的作用与缓冲区一样,可以防止栈指针的栈溢出。如果应用程序溢出到此缓冲区中,这个错误可能会导致 SIGSEGV 信号被发送给该线程。

12、设置线程的栈溢出保护区大小
int pthread_attr_setguardsize(pthread_attr_t *attr, size_t guardsize);
返回值:若是成功返回0,否则返回错误的编号
形 参:attr 指向一个线程属性的指针
guardsize 线程的栈保护区大小
说 明:参数提供了对栈指针溢出的保护。
  • 如果 guardsize 为零,则不会为使用 attr 创建的线程提供溢出保护区。
  • 如果 guardsize 大于零,则会为每个使用attr 创建的线程提供大小至少为 guardsize 字节的溢出保护区。缺省情况下,线程具有实现定义的非零溢出保护区。将 guardsize 的值向上舍入为可配置的系统变量 PAGESIZE 的倍数。请参见 sys/mman.h 中的PAGESIZE(4096字节)

注意:线程属性guardsize 控制着线程栈末尾之后用以避免溢出的扩展内存的大小这个属性默认设置为PAGESIZE个字节。可以把guardsize线程属性设为0,从而不允许属性的这种属性的行为发生:在这种情况下不会提供警戒缓冲区。同样地,如果对线程属性stackaddr(pthread_attr_setstack/pthread_attr_setstackaddr 函数)作了修改,系统就会假设我们会自己管理栈,并使警戒缓冲机制无效,等同于把guardsize线程属性设为0.

本文来源于以前写的博客:《posix多线程有感--线程高级编程(线程属性函数总结)》,并做了一些修订。但是不够全面,没有写出全部的属性。



UNIX环境高级编程——线程属性的更多相关文章

  1. UNIX环境高级编程——线程属性之分离属性

    说到线程的分离状态,我认为,之所以会有这个状态,是因为系统对某些线程的终止状态根本不感兴趣导致的. 我们知道,进程中的线程可以调用: int pthread_join(pthread_t tid, v ...

  2. UNIX环境高级编程——线程属性之并发度

    并发度控制着用户级线程可以映射的内核线程或进程的数目.如果操作系统的实现在内核级的线程和用户级的线程之间保持一对一的映射,那么改变并发度并不会有什么效果,因为所有的用户级线程都可能被调度到.但是,如果 ...

  3. UNIX环境高级编程——线程

    线程包含了表示进程内执行环境必需的信息,其中包括进程中标示线程的线程ID.一组寄存器值.栈.调度优先级和策略.信号屏蔽字.errno变量以及线程私有数据. 进程的所有信息对该进程的所有线程都是共享的, ...

  4. UNIX环境高级编程——线程同步之条件变量以及属性

    条件变量变量也是出自POSIX线程标准,另一种线程同步机制.主要用来等待某个条件的发生.可以用来同步同一进程中的各个线程.当然如果一个条件变量存放在多个进程共享的某个内存区中,那么还可以通过条件变量来 ...

  5. UNIX环境高级编程——线程同步之读写锁以及属性

    读写锁和互斥量(互斥锁)很类似,是另一种线程同步机制,但不属于POSIX标准,可以用来同步同一进程中的各个线程.当然如果一个读写锁存放在多个进程共享的某个内存区中,那么还可以用来进行进程间的同步, 互 ...

  6. Unix 环境高级编程---线程创建、同步、

    一下代码主要实现了linux下线程创建的基本方法,这些都是使用默认属性的.以后有机会再探讨自定义属性的情况.主要是为了练习三种基本的线程同步方法:互斥.读写锁以及条件变量. #include < ...

  7. UNIX环境高级编程——线程和fork

    当线程调用fork时,就为子进程创建了整个进程地址空间的副本.子进程通过继承整个地址空间的副本,也从父进程那里继承了所有互斥量.读写锁和条件变量的状态.如果父进程包含多个线程,子进程在fork返回以后 ...

  8. UNIX环境高级编程——线程同步之互斥量

    互斥量(也称为互斥锁)出自POSIX线程标准,可以用来同步同一进程中的各个线程.当然如果一个互斥量存放在多个进程共享的某个内存区中,那么还可以通过互斥量来进行进程间的同步. 互斥量,从字面上就可以知道 ...

  9. UNIX环境高级编程——线程和信号

    每个线程都有自己的信号屏蔽字,但是信号的处理是进程中所有线程共享的.这意味着尽管单个线程可以阻止某些信号,但当线程修改了与某个信号相关的处理行为以后,所有的线程都必须共享这个处理行为的改变.这样如果一 ...

随机推荐

  1. ScalaPB(0): 找寻合适的内部系统微服务集成工具

    前一段时间我们探讨了SDP的一个基于集群的综合数据平台解决方案,由多种数据库组成,包括:JDBC, Cassandra 及MongoDB.其中Cassandra和MongoDB属于分布式数据库,可以在 ...

  2. P2P技术概要

          P2P(Peer to Peer)也就是 对等网络,即对等计算机网络,是一种在对等者(Peer)之间分配任务和工作负载的分布式应用架构[1]  ,是对等计算模型在应用层形成的一种组网或网络 ...

  3. Linux下如何进入中文目录

    给Linux安装图形用户界面之后,会在工作目录中生成图片, 文档, 下载........等中文目录,以前不知道如何进入这些目录,感觉也没有必要,今天在火狐上下载了一个软件,默认在下载这个目录当中,实在 ...

  4. js 在iframe子页面获取父页面元素,或在父页面 获取iframe子页面的元素的几种方式

    用JS或jquery访问页面内的iframe,兼容IE/FF 注意:框架内的页面是不能跨域的! 假设有两个页面,在相同域下. index.html 文件内含有一个iframe: XML/HTML代码 ...

  5. Oracle10g以上sysaux表空间的维护和清理

    SYSAUX表空间在Oracle 10g中引入,其作为SYSTEM表空间的辅助表空间.之前,一些使用独立表空间或系统表空间的数据库组件,现在SYSAUX表空间中存在.通过分离这些组件,减轻了SYSTE ...

  6. 好用的jquery.animateNumber.js数字动画插件

    在做公司的运营报告页面时,有一个数字累计增加的动画效果,一开始,毫无头绪,不知如何下手,于是上网查资料,发现大多都是用的插件来实现的,那么今天,我也来用插件jquery.animateNumber.j ...

  7. hasattr(),getattr(),setattr()的使用

    # 首先你有一个command.py文件,内容如下,这里我们假若它后面还有100个方法 class MyObject(object): def __init__(self): self.x = def ...

  8. Lucene初体验——Hello Word实现

    1.创建索引 /** * 建立索引 */ public void index(){ IndexWriter writer=null; try { //1.创建Directory //Directory ...

  9. PHP MySQL Where 子句

    WHERE 子句 WHERE 子句用于提取满足指定标准的的记录. 语法 SELECT column_name(s) FROM table_name WHERE column_name operator ...

  10. 实验-使用VisualVM或JConsole进行对程序进行性能分析

    参考资料: 性能分析神器VisualVM java可视化监控工具 完成下列任务: 1.分析内存堆 使用+进行频繁的字符串拼接 2.CPU性能分析 3.线程分析 编程比较以下几个方法所创建的线程 Exe ...