线程属性(多线程编程笔记)

本文详细介绍了在多线程编程中如何使用线程属性,包括初始化、配置和销毁线程属性对象,以及设置线程的分离状态、栈溢出保护区大小、范围、并行级别、调度策略等相关属性。通过线程属性,可以更精确地控制线程的行为,提高代码的可移植性和应用程序的管理效率。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

线程属性

前篇介绍了使用缺省属性创建线程的基本原理。本章论述如何在创建线程时设置
属性。
注– 只有pthreads 使用属性和取消功能。本章中介绍的API 仅适用于POSIX 线程。除此
之外,Solaris 线程和pthreads 的功能大致是相同的。

属性对象

通过设置属性,可以指定一种不同于缺省行为的行为。使用pthread_create(3C)创建
线程时,或初始化同步变量时,可以指定属性对象。缺省值通常就足够了。
属性对象是不透明的,而且不能通过赋值直接进行修改。系统提供了一组函数,用于
初始化、配置和销毁每种对象类型。
初始化和配置属性后,属性便具有进程范围的作用域。使用属性时最好的方法即是在
程序执行早期一次配置好所有必需的状态规范。然后,根据需要引用相应的属性对
象。
使用属性对象具有两个主要优点。
■ 使用属性对象可增加代码可移植性。
即使支持的属性可能会在实现之间有所变化,但您不需要修改用于创建线程实体的
函数调用。这些函数调用不需要进行修改,因为属性对象是隐藏在接口之后的。
如果目标系统支持的属性在当前系统中不存在,则必须显式提供才能管理新的属
性。管理这些属性是一项非常容易的移植任务,因为只需在明确定义的位置初始化
属性对象一次即可。
■ 应用程序中的状态规范已被简化。

例如,假设进程中可能存在多组线程。每组线程都提供单独的服务。每组线程都有
各自的状态要求。
在应用程序执行初期的某一时间,可以针对每组线程初始化线程属性对象。以后所
有线程的创建都会引用已经为这类线程初始化的属性对象。初始化阶段是简单和局
部的。将来就可以快速且可靠地进行任何修改。
在进程退出时需要注意属性对象。初始化对象时,将为该对象分配内存。必须将此内
存返回给系统。pthreads 标准提供了用于销毁属性对象的函数调用。

初始化属性

请使用pthread_attr_init(3C)将对象属性初始化为其缺省值。存储空间是在执行期间
由线程系统分配的。

pthread_attr_init 语法

int pthread_attr_init(pthread_attr_t *tattr);
#include <pthread.h>
pthread_attr_t tattr;
int ret;
/* initialize an attribute to the default value */
ret = pthread_attr_init(&tattr); 

表1 给出了属性(tattr) 的缺省值。

属性 结果
scope PTHREAD_SCOPE_PROCESS 新线程与进程中的其他线程发生竞争。
detachstate PTHREAD_CREATE_JOINABLE 线程退出后,保留完成状态和线程ID。
stackaddr NULL 新线程具有系统分配的栈地址。
stacksize 0 新线程具有系统定义的栈大小。
priority 0 新线程的优先级为0。
inheritsched PTHREAD_EXPLICIT_SCHED 新线程不继承父线程调度优先级。
schedpolicy SCHED_OTHER 新线程对同步对象争用使用Solaris 定义的固定优先级。线程将一直运行,直到被抢占或者直到线程阻塞或停止为止。

pthread_attr_init 返回值
pthread_attr_init()成功完成后将返回零。其他任何返回值都表示出现了错误。如果
出现以下情况,该函数将失败并返回对应的值。
ENOMEM
描述: 如果未分配足够的内存来初始化线程属性对象,将返回该值。

销毁属性

请使用pthread_attr_destroy(3C) 删除初始化期间分配的存储空间。属性对象将会无
效。

pthread_attr_destroy语法

int pthread_attr_destroy(pthread_attr_t *tattr);
#include <pthread.h>
pthread_attr_t tattr;
int ret;
/* destroy an attribute */
ret = pthread_attr_destroy(&tattr);

pthread_attr_destroy返回值
pthread_attr_destroy()成功完成后将返回零。其他任何返回值都表示出现了错误。如
果出现以下情况,该函数将失败并返回对应的值。
EINVAL
描述: 指示tattr 的值无效。

设置分离状态

如果创建分离线程(PTHREAD_CREATE_DETACHED),则该线程一退出,便可重用其线程ID
和其他资源。如果调用线程不准备等待线程退出,请使用pthread_attr_setdetachstate(3C)

pthread_attr_setdetachstate(3C) 语法

int pthread_attr_setdetachstate(pthread_attr_t *tattr,int detachstate);
#include <pthread.h>
pthread_attr_t tattr;
int ret;
/* set the thread detach state */
ret = pthread_attr_setdetachstate(&tattr,PTHREAD_CREATE_DETACHED); 

如果使用PTHREAD_CREATE_JOINABLE创建非分离线程,则假设应用程序将等待线程完
成。也就是说,程序将对线程执行pthread_join()
无论是创建分离线程还是非分离线程,在所有线程都退出之前,进程不会退出。

注– 如果未执行显式同步来防止新创建的分离线程失败,则在线程创建者从
pthread_create()返回之前,可以将其线程ID 重新分配给另一个新线程。
非分离线程在终止后,必须要有一个线程用join 来等待它。否则,不会释放该线程的
资源以供新线程使用,而这通常会导致内存泄漏。因此,如果不希望线程被等待,请
将该线程作为分离线程来创建。

示例1创建分离线程

#include <pthread.h>
pthread_attr_t tattr;
pthread_t tid;
void *start_routine;
void arg
int ret; 

/* initialized with default attributes */
ret = pthread_attr_init (&tattr);
ret = pthread_attr_setdetachstate (&tattr,PTHREAD_CREATE_DETACHED);
ret = pthread_create (&tid, &tattr, start_routine, arg); 

pthread_attr_setdetachstate 返回值
pthread_attr_setdetachstate() 成功完成后将返回零。其他任何返回值都表示出现了
错误。如果出现以下情况,该函数将失败并返回对应的值。
EINVAL
描述: 指示detachstate 或tattr 的值无效。

获取分离状态

请使用pthread_attr_getdetachstate(3C) 检索线程创建状态(可以为分离或连接)。

pthread_attr_getdetachstate 语法

int pthread_attr_getdetachstate(const pthread_attr_t *tattr,
        int *detachstate)
#include <pthread.h>
pthread_attr_t tattr;
int detachstate;
int ret;

/* get detachstate of thread */
ret = pthread_attr_
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值