必威体育Betway必威体育官网
当前位置:首页 > IT技术

UNIX(编程-线程控制):02---线程创建属性(pthread_attr_t)

时间:2019-08-18 10:14:32来源:IT技术作者:seo实验室小编阅读:51次「手机版」
 

pthread_t

一、线程属性结构体(pthread_attr_t)

  • 此结构的内容包含的就是线程的属性值
  • 线程创建函数pthread_create的参数2就是使用此结构为线程设置初始属性值。线程的创建见:https://blog.csdn.net/qq_41453285/article/details/89293532

二、线程属性

POSIX.1定义的线程属性如下(POSIX.1还为线程执行调度选项定义了额外的属性,用以支持实时应用,这里不做讨论):

  • 下面这些值都是存在于pthread_attr_t结构中的,如果想要设置某一个属性的值,需要用各自的函数进行设置,下面会介绍

三、线程属性结构体的创建与销毁

#include <pthread.h>
int pthread_attr_init(pthread_attr_t *attr);
int pthread_attr_destroy(pthread_attr_t *attr);

//返回值:成功返回0;失败返回错误编号

pthread_attr_init函数:

  • 功能:用来对线程属性值进行初始化
  • 注意:调用此函数之后,属性结构体的属性都是系统默认值,如果想要设置其他属性,还需要调用不同的函数进行设置

pthread_attr_destory函数:

  • 功能:用来反初始化(销毁)属性。如果pthread_attr_init函数初始化的线程属性是动态分配的,那么此函数就会释放线程属性的内存空间
  • pthread_attr_destory函数会用无效的值初始化属性对象,因此用此函数反初始化属性之后,属性就不能供pthread_create函数使用了

四、分离状态属性的设置/获取(detachstate)

#include <pthread.h>
int pthread_attr_setdetachstate(pthread_attr_t *attr, int detachstate);
int pthread_attr_getdetachstate(const pthread_attr_t *restrict attr, int *detachstate);

//返回值:成功返回0;失败返回错误编号

pthread_attr_setdetachstate函数:

  • 功能:用来设置pthread_attr_t结构的detachstate属性的值

参数2如下表:

PTHREAD_CREATE_DETACHED 用此值赋值给pthread_attr_t结构,那么pthread_create函数使用pthread_attr_t结构创建线程时,线程以分离状态启动线程
PTHREAD_CREATE_JOINABLE 用此值赋值给pthread_attr_t结构,那么pthread_create函数使用pthread_attr_t结构创建线程时,线程正常方式启动线程

pthread_attr_getdetachstate函数:

  • 获得参数1pthread_attr_t结构中的detachstate值,并将值存放在参数2返回给调用者

五、栈位置属性的设置/获取(stackaddr)

使用前提

  • 对于遵循POSIX标准的操作系统来说,不一定支持线程栈属性,但是对于循序Single UNIX Specification中的XSI选项的系统来说,支持线程栈属性就是必须的
  • 可以在编译阶段使用_POSIX_THREAD_ATTR_STACKADDR和_POSIX_THREAD_ATTR_STACKSIZE符号来检查系统是否支持每一个线程属性。或者在运行阶段把_SC_THREAD_ATTR_STACKADDR、_SC_THREAD_ATTR_STACKSIZE参数传给sysconf函数,检查运行时系统对线程栈属性的支持情况
#include <pthread.h>
int pthread_attr_setstack(pthread_attr_t *attr,void *stackaddr,size_t stacksize);
int pthread_attr_getstack(const pthread_attr_t *attr, void **restrict stackaddr,size_t *restrict stacksize);

//返回值:成功返回0;失败返回错误编号

 pthread_attr_setstack函数:

  • 为什么使用此函数:对于进程来说,虚地址空间的大小是固定的。对于进程来说只有一个栈,所以它的大小通常不是问题。但是对于线程来说,同样大小的虚地址空间被所有的线程栈共享。如果应用程序使用了很多线程,以至于这些线程栈的累计大小超过了可用的虚地址空间,就需要减少默认的线程栈大小。另一方面,如果线程调用的函数分配了大量的自动变量,或者调用的函数设计许多很深的栈帧,那么需要的栈大小可能要比默认的大
  • stackaddr参数:如果线程栈的虚地址空间用完了,那可以使用malloc或mmap为可替代的栈分配空间,并将栈的地址赋值给此参数。此参数指定的地址可以用作线程栈的内存范围中的最低寻址地址,改地址与处理器结构相应的边界对齐。(注意:stackaddr被定义为栈的最低内存地址,但并一定是栈的开始位置。对于一个给定的处理器结构来说,如果栈是从高低值向底地址方向增长的,那么stackaddr将是栈结尾位置,而不是开始位置)
  • stacksize参数:stackaddr所指地址空间的大小

 pthread_attr_getstack函数:

  • 功能:得到线程栈的地址

六、栈大小属性的设置/获取(stacksize)

#include <pthread.h>
int pthread_attr_setstacksize(pthread_attr_t *attr, size_t stacksize);
int pthread_attr_getstacksize(const pthread_attr_t *restrict  attr, size_t *restrict stacksize);

//返回值:成功返回0;失败返回错误编号

pthread_attr_setstacksize函数:

  • 功能:如果希望改变默认的栈大小,但又不想自己处理线程栈的分配问题,可以使用此函数设置线程的栈大小
  • stacksize参数:设置的线程栈大小。(限制:栈大小不能小于PTHREAD_STACK_MIN)

pthread_attr_getstacksize函数:

  • 功能:得到线程的栈大小

七、栈溢出缓冲区属性的设置/获取(guardsize)

何为guardsize属性:

  • 此属性控制着线程栈末尾之后用来避免栈溢出的扩展内存的大小
  • 这个属性默认值由具体实现来定义,但常用值是系统页大小
  • 如果guardsize属性被修改了,操作系统可能会把它取为页大小的整数倍。如果线程的栈指针溢出到警戒区域,应用程序就可能通过信号接收到出错信息
#include <pthread.h>
int pthread_attr_setguardsize(pthread_attr_t *attr, size_t guardsize);
int pthread_attr_getguardsize(const pthread_attr_t *restrict  attr, size_t *restrict guardsize);

//返回值:成功返回0;失败返回错误编号

pthread_attr_setguardsize函数:

  • 功能:设置栈溢出扩展内存的大小
  • guardsize参数:栈溢出的扩展内存大小。(如果此参数设置为0,表示不提供栈溢出扩展内存,进而栈警戒缓冲区机制无效)
  • 注意(重点):如果我们修改了线程的stackaddr属性,系统就认为我们自己管理栈,调用此函数设置栈溢出扩展内存大小也不起作用了

pthread_attr_getguardsize函数:

  • 功能:得到栈溢出扩展内存的大小

相关阅读

5个步骤,教你瞬间明白线程和线程安全

作者 | 一个程

深入理解Java多线程与并发编程

     线程三大特性 多线程有三大特性,原子性、可见性、有序性2.1什么是原子性      即一个操作或者多个操作要么全部执行并

【带图】讲解offsetHeight、offsetLeft、clientWidth

1.偏移量元素的可见大小由其高度、宽度决定,包括所有内边距、滚动条和边框的大小(注意,不包括外边距)。offsetHeight:元素在垂直方向上

进程与线程的区别和联系

程序并不能单独执行,只有将程序加载到内存中,系统为他分配资源后才能够执行,这种执行的程序称之为进程,也就是说进程是系统进行资源分

Android多线程:HandlerThread详细使用手册

前言 多线程的应用在Android开发中是非常常见的,常用方法主要有:继承Thread类 实现Runnable接口 Handler AsyncTask HandlerThread

分享到:

栏目导航

推荐阅读

热门阅读