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. CNN中的经典结构之AlexNet

    AlexNet的基本结构 Alexnet是由5个卷积层和三个全连接层组成,一共8个权重层(池化层不是权重层因为其没有参数),其中ReLU激活函数作用在每个卷积层和全连接层上,在第一个卷积层和第二个卷积 ...

  2. map内置函数、lambda表达式、快捷生成想要的列表、filter内置函数

      map函数                             语法 map(function, iterable, ...) 参数 function -- 函数,有两个参数 iterable ...

  3. 详解linux进程间通信-管道 popen函数 dup2函数

    前言:进程之间交换信息的唯一方法是经由f o r k或e x e c传送打开文件,或通过文件系统.本章将说明进程之间相互通信的其他技术-I P C(InterProcess Communication ...

  4. 编程英语之KNN算法

    School of Computer Science The University of Adelaide   Artificial Intelligence Assignment 2   Semes ...

  5. JS判断PC还是移动端打开网页

    最近在做移动端网站,也需兼容PC端.还没找到更好的方法,只能用javascr判断用户是在PC端打开还是移动端打开. JS判断 var isPC = function (){    var userAg ...

  6. MySQL UPDATE 查询

    MySQL UPDATE 查询 如果我们需要修改或更新MySQL中的数据,我们可以使用 SQL UPDATE 命令来操作.. 语法 以下是 UPDATE 命令修改 MySQL 数据表数据的通用SQL语 ...

  7. PHP XML 函数

    PHP XML Parser 简介 XML 函数允许您解析 XML 文档,但无法对其进行验证. XML 是一种用于标准结构化文档交换的数据格式.您可以在我们的 XML 教程 中找到更多有关 XML 的 ...

  8. lucene创建索引

    创建索引. 1.lucene下载. 下载地址:http://archive.apache.org/dist/lucene/java/. lucene不同版本之间有不小的差别,这里下载的是lucene ...

  9. Dynamics CRM REST Builder

    今天介绍个很棒的工具叫CRM REST Builder,不管是2016之前的odata查询或者现在的web api都不在话下,界面如下,选项非常丰富 这里以retrieve multiple举个例子, ...

  10. oracle11实战详解

    因为最近可以学习oracle了,所以昨天把oracle装好了,装的时候因为种种不知名的原因,把我的mysql居然连连不上了.说实话如果自己看教程安装的话还是有一点小复杂的,特别是对于我这种学渣来说,我 ...