线程控制之线程限制和线程属性

本文来自个人博客:https://dunkwan.cn

线程限制

Single UNIX Specification 定义了与线程操作有关的一些限制,下图是列出了这些限制。

下图则给出了这些限制在4中不同平台上的限制值。”没有确定的限制“并不意味着是无限制。

线程属性

pthread接口允许我们通过设置每个对象关联的不同属性来细调线程和同步对象的行为。通常,管理这些属性的函数都遵循相同的模式,主要有以下特点:

  1. 每个对象与它自己类型的属性对象进行关联。(线程与线程属性关联、互斥量与互斥量属性关联等。)
  2. 有一个初始化函数,把属性设置为默认值。
  3. 还有一个销毁属性对象的函数。
  4. 每个属性都有一个从属性对象中获取属性值的函数。
  5. 每个属性都有一个设置属性值的函数。

pthread_attr_init函数用于初始化pthread_attr_t结构,并使用该结构对线程属性进行修改。pthread_attr_destroy函数用于释放与该属性相关联的资源。

#include <pthread.h>
int pthread_attr_init(pthread_attr_t *attr);
int pthread_attr_destroy(pthread_attr_t *attr);
两个函数的返回值:若成功,返回0;否则,返回错误编码。

下图给出了POSIX.1定义的线程属性在4种不同平台上的支持情况。

下面就对上图的四种不同属性的有关函数进行讨论。

detachstate属性

可以使用pthread_attr_setdetachstate函数把线程属性detachstate设置成以下合法值之一:PTHREAD_CREATE_DETACHED,以分离状态启动线程;或者PTHREAD_CREATE_JOINABLE,正常启动线程,应用程序可以获取线程的终止状态。

可以调用pthread_attr_getdetachstate函数获取当前的detachstate线程属性。第二个参数所指向的整数要么设置成PTHREAD_CREATE_DETACHEDPTHREAD_CREATE_JOINABLE,具体取决于给定的pthread_attr_t结构中的属性值。

#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;否则,返回错误编码。

下面给出一个以分离状态创建线程的函数。

#include "apue.h"
#include <pthread.h>

int
makethread(void *(*fn)(void *), void *arg)
{
	int				err;
	pthread_t		tid;
	pthread_attr_t	attr;

	err = pthread_attr_init(&attr);
	if (err != 0)
		return(err);
	err = pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED);
	if (err == 0)
		err = pthread_create(&tid, &attr, fn, arg);
	pthread_attr_destroy(&attr);
	return(err);
}

stackaddr属性

对于遵循POSIX标准的操作系统而言,并不一定要支持线程栈属性,但是对于遵循Single UNIX Specification中XSI选项的系统来说,支持线程栈属性就是必需的。

使用函数pthread_attr_getstackpthread_attr_setstack对线程属性进行管理。

#include <pthread.h>
int pthread_attr_getstack(const pthread_attr_t *restrict attr, void **restrict stackaddr, size_t *restrict stacksize);
int pthread_attr_setstack(pthread_attr_t *attr, void *stackaddr, size_t stacksize);
两个函数的返回值:若成功,返回0;否则,返回错误编码。

stacksize属性

pthread_attr_getstacksizepthread_attr_setstacksize函数读取或设置线程属性stacksize

#include <pthread.h>
int pthread_attr_getstacksize(const pthread_attr_t *restrict attr, size_t *restrict stacksize);
int pthread_attr_setstacksize(pthread_attr_t *attr, size_t stacksize);
两个函数的返回值:若成功,返回0;否则,返回错误编码。

设置stacksize属性时,选择的stacksize不能小于PTHREAD_STACK_MIN

guardsize属性

guardsize线程属性控制着线程栈末尾之后用以避免栈溢出的扩展内存的大小。这个属性默认值是具体实现定义的,但常用值是系统页大小。将guardsize设置为0表示不提供警戒缓冲区。同样,如果修改了线程属性stackaddr,系统就认为我们将自己管理栈,进而使栈警戒缓冲区机制无效,这等同于把guardsize设置为0。

#include <pthread.h>
int pthread_attr_getguardsize(const pthread_attr_t *restrict attr, size_t *restrict guardsize);
int pthread_attr_setguardsize(pthread_attr_t *attr, size_t guardsize);
两个函数返回值:若成功,返回0;否则,返回错误编号。

如果guardsize线程属性被修改了,操作系统可能把它取为页大小的整数倍。如果线程的栈指针溢出到警戒区域,应用程序就可能通过信号接收到出错信息。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值