当前位置: 首页 > news >正文

Linux线程(六)线程属性详解

如前所述,调用 pthread_create()创建线程,可对新建线程的各种属性进行设置。在 Linux 下,使用pthread_attr_t 数据类型定义线程的所有属性,本书并不打算详细讨论这些属性,以介绍为主,简单地了解下线程属性。

调用 pthread_create()创建线程时,参数 attr 设置为 NULL,表示使用属性的默认值创建线程。如果不使用默认值,参数 attr 必须要指向一个 pthread_attr_t 对象,而不能使用 NULL。当定义 pthread_attr_t 对象之后 ,需要 使用 pthread_attr_init()函 数 对 该对象进 行初始 化操作 ,当对象 不再使 用时, 需要使用pthread_attr_destroy()函数将其销毁,函数原型如下所示:

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

使用这些函数需要包含头文件<pthread.h>,参数 attr 指向一个 pthread_attr_t 对象,即需要进行初始化的线程属性对象。在调用成功时返回 0,失败将返回一个非 0 值的错误码。

调用 pthread_attr_init()函数会将指定的 pthread_attr_t 对象中定义的各种线程属性初始化为它们各自对应的默认值。

pthread_attr_t 数据结构中包含的属性比较多,本小节并不会一一点出,可能比较关注属性包括:线程栈的位置和大小、线程调度策略和优先级,以及线程的分离状态属性等。Linux 为 pthread_attr_t 对象的每种属性提供了设置属性的接口以及获取属性的接口。

线程栈属性

每个线程都有自己的栈空间,pthread_attr_t 数据结构中定义了栈的起始地址以及栈大小,调用函数pthread_attr_getstack()可以获取这些信息,函数 pthread_attr_setstack()对栈起始地址和栈大小进行设置,其函数原型如下所示:

#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 **stackaddr, size_t *stacksize);

使用这些函数需要包含头文件<pthread.h>,函数 pthread_attr_getstack(),参数和返回值含义如下:

attr:

参数 attr 指向线程属性对象。

stackaddr:

调用 pthread_attr_getstack()可获取栈起始地址,并将起始地址信息保存在*stackaddr 中;

stacksize:调用 pthread_attr_getstack()可获取栈大小,并将栈大小信息保存在参数 stacksize 所指向的内存中;

返回值:成功返回 0,失败将返回一个非 0 值的错误码。

函数 pthread_attr_setstack(),参数和返回值含义如下:

attr:参数 attr 指向线程属性对象。

stackaddr:设置栈起始地址为指定值。

stacksize:设置栈大小为指定值;

返回值:成功返回 0,失败将返回一个非 0 值的错误码。

如果想单独获取或设置栈大小、栈起始地址,可以使用下面这些函数:

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

int pthread_attr_getstacksize(const pthread_attr_t *attr, size_t *stacksize);

int pthread_attr_setstackaddr(pthread_attr_t *attr, void *stackaddr);

int pthread_attr_getstackaddr(const pthread_attr_t *attr, void **stackaddr);

使用示例

创建新的线程,将线程的栈大小设置为 4Kbyte。

//示例代码 11.9.1 设置线程栈大小 pthread_attr_getstack()
#include <stdio.h>
#include <stdlib.h>
#include <pthread.h>
#include <string.h>
static void *new_thread_start(void *arg) {puts("Hello World!");return (void *)0; }
int main(int argc, char *argv[])
{pthread_attr_t attr;size_t stacksize;pthread_t tid;int ret;/* 对 attr 对象进行初始化 */pthread_attr_init(&attr);/* 设置栈大小为 4K */pthread_attr_setstacksize(&attr, 4096);/* 创建新线程 */ret = pthread_create(&tid, &attr, new_thread_start, NULL);if (ret) {fprintf(stderr, "pthread_create error: %s\\n", strerror(ret));exit(-1);}/* 等待新线程终止 */ret = pthread_join(tid, NULL);if (ret) {fprintf(stderr, "pthread_join error: %s\\n", strerror(ret));exit(-1);}/* 销毁 attr 对象 */pthread_attr_destroy(&attr);exit(0);
}

分离状态属性

前面介绍了线程分离的概念,如果对现已创建的某个线程的终止状态不感兴趣,可以使用

pthread_detach()函数将其分离,那么该线程在退出时,操作系统会自动回收它所占用的资源。

如果我们在创建线程时就确定要将该线程分离,可以修改 pthread_attr_t 结构中的 detachstate 线程属性,让线程一开始运行就处于分离状态。调用函数 pthread_attr_setdetachstate()设置 detachstate 线程属性,调用

pthread_attr_getdetachstate()获取 detachstate 线程属性,其函数原型如下所示:

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

需要包含头文件<pthread.h>,参数 attr 指向 pthread_attr_t 对象;调用 pthread_attr_setdetachstate()函数将

detachstate 线程属性设置为参数 detachstate 所指定的值,参数 detachstate 取值如下:

  • PTHREAD_CREATE_DETACHED:新建线程一开始运行便处于分离状态,以分离状态启动线程,无法被其它线程调用 pthread_join()回收,线程结束后由操作系统收回其所占用的资源;
  • PTHREAD_CREATE_JOINABLE:这是 detachstate 线程属性的默认值,正常启动线程,可以被其它线程获取终止状态信息。

函数 pthread_attr_getdetachstate()用于获取 detachstate 线程属性,将 detachstate 线程属性保存在参数

detachstate 所指定的内存中。

使用示例

示例代码 11.9.2 给出了以分离状态启动线程的示例。

//示例代码 11.9.2 以分离状态启动线程
#include <stdio.h>
#include <stdlib.h>
#include <pthread.h>
#include <string.h>
#include <unistd.h>static void *new_thread_start(void *arg) {puts("Hello World!");return (void *)0; 
}int main(int argc, char *argv[])
{pthread_attr_t attr;pthread_t tid;int ret;/* 对 attr 对象进行初始化 */pthread_attr_init(&attr);/* 设置以分离状态启动线程 */pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED);/* 创建新线程 */ret = pthread_create(&tid, &attr, new_thread_start, NULL);if (ret) {fprintf(stderr, "pthread_create error: %s\\n", strerror(ret));exit(-1);}sleep(1);/* 销毁 attr 对象 */pthread_attr_destroy(&attr);exit(0);
}


http://www.mrgr.cn/news/42422.html

相关文章:

  • 浅谈C语言中的字符串和数组
  • 【正则表达式】粗浅学习
  • 新闻推荐系统:Spring Boot框架详解
  • 【2024保研经验帖】武汉大学测绘遥感国家重点实验室夏令营(计算机向)
  • YOLOv11改进 | Conv篇 | YOLOv11引入RFAConv
  • 吴恩达教授阐述人类在AI时代生存的重要技能
  • 利用Spring Boot打造新闻推荐解决方案
  • AI学习指南深度学习篇-权重正则化Python实践
  • Linux中的进程信号
  • 【AI知识点】小世界网络(Small-World Networks)
  • 探索未来:mosquitto-python,AI领域的新宠
  • Redis Sorted Set 跳表的实现原理与分析
  • 【C++前缀和】1895. 最大的幻方|1781
  • Spring Boot驱动的智能新闻推荐引擎
  • spring揭秘25-springmvc05-过滤器与拦截器区别(补充)
  • 8个最受欢迎的AI网页抓取工具
  • 使用 pexports.exe 从 DLL 生成 .lib 文件的详细教程
  • 【宽搜】1. 层序遍历模板讲解
  • 20240930编译orangepi5的Android12使用HDMI0输出
  • 小红书三面被问 RAG 原理,秒挂…