嵌入式Linux-线程属性

news2024/11/24 12:31:47

1. 线程的属性

1.1 概念

如前所述,调用 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);

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

typedef struct
{
       int                       detachstate;   // 线程的分离状态
       int                       schedpolicy;   // 线程调度策略
       structsched_param         schedparam;    // 线程的调度参数
       int                       inheritsched;  // 线程的继承性
       int                       scope;         // 线程的作用域
       size_t                    guardsize;     // 线程栈末尾的警戒缓冲区大小
       int                       stackaddr_set; // 线程的栈设置
       void*                     stackaddr;     // 线程栈的位置
       size_t                    stacksize;     // 线程栈的大小
} pthread_attr_t;

1.2 线程栈属性

每个线程都有自己的栈空间,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);

下面注意讲解一下参数的含义:

  1. pthread_attr_setstack()函数
参数含义
attr参数attr 指向线程属性对象
stackaddr设置栈起始地址为指定值
stacksize设置栈大小为指定值
  1. pthread_attr_getstack()函数
参数含义
attr参数attr 指向线程属性对象
stackaddr调用 pthread_attr_getstack()可获取栈起始地址,并将起始地址信息保存在*stackaddr 中
stacksize调用 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 *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);

讲了这么多,结合1和2我们来一个实例:
创建新的线程,将线程的栈大小设置为 4Kbyte。

#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);
}

在这里插入图片描述

1.3 分离状态属性

前面介绍了线程分离的概念,如果对现已创建的某个线程的终止状态不感兴趣,可以使用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_attr_setdetachstate()函数将detachstate 线程属性设置为参数 detachstate 所指定的值,参数 detachstate 取值如下:

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

函数 pthread_attr_getdetachstate()用于获取 detachstate 线程属性,将 detachstate 线程属性保存在参数detachstate 所指定的内存中。

以分离状态启动线程的示例:

#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);
}

由于现象基本一样,但是本示例的内部的原理是分离了线程,由系统自动回收资源的。

本文参考正点原子的嵌入式LinuxC应用编程。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/188969.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

Three.js 初阶入门篇(一)

系列文章目录 文章目录系列文章目录学习背景一、什么是3D&#xff08;直接看作品吧&#xff09;&#xff1f;汽车作品欣赏鼠标可以随意转动角度打开机盖&#xff08;交互效果&#xff09;尾部3D链接&#x1f517;如下&#xff08;链接打开会有一些慢&#xff09;二、如何创建一…

零入门容器云网络实战-7->Mac环境下为虚拟机磁盘空间进行扩容

在Mac环境下&#xff0c;使用PD软件创建的虚拟机磁盘空间不够时&#xff0c;如何扩容呢&#xff1f; 主要分两大步骤&#xff1a; 先通过PD界面&#xff0c;设置增加多少空间进入虚拟机里&#xff0c;通过fdisk等相关命令&#xff0c;使其增加的空间生效 1、第一大步&#xf…

机器学习之线性模型

定义 线性模型非常常见&#xff0c;但详细了解其中原理是必要的。 一般将样本特征进行线性组合达到预测的目标&#xff0c;如表达式yf(X;W)byf(X;W)byf(X;W)b,其中XXX为输入的样本数据&#xff0c;WWW为权重系数&#xff0c;bbb为偏置系数。 如对于图片样本&#xff0c;一种…

兔年春晚一大怪像,影视演员变成了万能,专业歌手却被晾在一边

怪事年年有&#xff0c;今年特别多。谁也没有想到&#xff0c;兔年春节还没有过去&#xff0c;就出现了一种奇怪的现象。中央电视台春晚&#xff0c;曾经执全国春晚之牛耳&#xff0c;然而谁能想到&#xff0c;四十多年后的今天&#xff0c;曾经的扛把子却变成了鸡肋。 今年央视…

【C++初阶】七、STL---vector(总)|vector的介绍|vector的使用

目录 一、vector的介绍 二、vector的使用 2.1 Construct 2.2 operator 2.3 Iterators 2.4 Capacity 2.5 Element access 2.6 Modifiers 一、vector的介绍 前面学习了 string类&#xff0c;所以 vector 的学习成本很低&#xff0c;因为接口都大致相同&#xff0c;功能也…

【促进开发】上海道宁与DHTMLX为您提供易于使用且功能丰富的JavaScript组件

DHTMLX提供 有效且专业设计的 JavaScript/HTML5工具 使开发人员 能够以更少的时间和精力 创建具有丰富界面和快速性能的 复杂Web和移动应用程序 DHTMLX使用 JavaScript UI 库促进开发 易于使用且功能丰富的 JavaScript组件 非常适合您在任何领域和 任何复杂性中的解…

SpringCloud微服务项目实战 - 7.kafka及文章上下架

一步一步地苦熬苦掖&#xff0c;终于我们也看见了花团锦簇&#xff0c;我们也知道了彩灯佳话。那一夜&#xff0c;我也曾梦见百万雄兵。 系列文章目录 项目搭建App登录及网关App文章自媒体平台&#xff08;博主后台&#xff09;内容审核(自动)延迟任务 文章目录系列文章目录一…

并查集应用

一、并查集模板 int find(int x) {if(p[x]!x) p[x]find(p[x]);return p[x]; }并查集高效率的核心是一旦更新过一次后&#xff0c;就会将路径压缩掉&#xff0c;避免后续重复遍历路径。 二、并查集应用 1、格子游戏 分析&#xff1a;每构成一个方框&#xff0c;当最后两个点连…

RA4M2开发(2)----基于IIC驱动OLED

概述 在e2studio中创建新的工程并导入必要的文件&#xff0c;包括I2C驱动代码和SSD1306 OLED显示驱动代码。配置RA4M2的I2C接口&#xff0c;使其作为I2C master进行通信。初始化SSD1306 OLED显示驱动代码&#xff0c;并配置显示屏的物理地址和分辨率。通过I2C驱动代码将数据写…

【Linux】初识环境变量

文章目录环境变量引入初见环境变量和环境变量有关的指令如何通过代码获取环境变量getenv()main函数的命令行参数第三方变量environ程序变量可以继承给子进程环境变量引入 Linux中有各种指令&#xff0c; 每个指令其实都是一个可执行程序&#xff1a; 和我们自己写的C语言代码…

API自动化测试【postman生成报告】

PostMan生成测试报告有两种&#xff1a; 1、控制台的模式 2、HTML的测试报告 使用到一个工具newman Node.js是前端的一个组件&#xff0c;主要可以使用它来开发异步的程序。 一、控制台的模式 1、安装node.js 双击node.js进行安装&#xff0c;安装成功后在控制台输入node…

Ansys Zemax | 多模光纤耦合

本文展示了利用几何图像分析特性来计算多模光纤耦合效率的方法。 还有使用IMAE操作数优化多模光纤耦合效率的方法。该方法只适用于包含大量模式的多模光纤。 下载 联系工作人员获取附件 简介 我们可以使用OpticStudio中的几何图像分析&#xff08;Geometric Image Analysi…

已解决error: legacy-instal1-failure

已解决&#xff08;pip install wxPython安装失败&#xff09;error: legacy-instal1-failure Encountered error while trying to install package.wxPython note: This is an issue with the package mentioned above&#xff0c;not pip. hint : See above for output from …

ChatGPT 回答什么是敏捷测试

Jenkins 官方文档&#xff1a;https://jenkins.io/doc/JUnit 插件文档&#xff1a;JUnit | Jenkins pluginTestNG 插件文档&#xff1a;https://plugins.jenkins.io/testng-plugin/Jenkins 教程&#xff1a;https://jenkins.io/doc/tutorials/JUnit 教程&#xff1a;JUnit 5 Us…

舆情监测软件报价方案,TOOM舆情监控软件多少钱?

舆情监测软件的价格因公司不同而有所差异&#xff0c;通常在几百元至数千元不等。价格还可能受到功能复杂度、数据量、使用时长等因素的影响。建议您联系多家软件开发商或销售代表&#xff0c;对比各家的产品和报价&#xff0c;以找到适合您需求和预算的解决方案。舆情监测软件…

算法训练营DAY46|139.单词拆分、多重背包的介绍

这一期到了背包问题的最后一期&#xff0c;主要讲解一道leetcodee题&#xff0c;和对多重背包的一些简单介绍&#xff0c;由于leetcode没有对于多重背包的具体问题&#xff0c;且面试基本不会问到多重背包所以只是作为科普。 139. 单词拆分 - 力扣&#xff08;LeetCode&#x…

缺省参数,函数重载,引用的使用(C++)

前言 本文主要讲解的是缺省参数&#xff0c;函数重载&#xff0c;引用的使用. 文章目录 目录 前言 一、缺省参数是什么&#xff1f; 1.缺省参数的分类 二、函数重载是什么&#xff1f; 三、引用是什么&#xff1f; 1.引用特性 总结 提示&#xff1a;以下是本篇文章正文内容&am…

java中的NIO,BIO,AIO

IO&#xff0c;input和output&#xff0c;Java 为 I/O 提供了强大的而灵活的支持&#xff0c;使其更广泛地应用到文件传输和网络编程中。 IO是什么&#xff1f;为什么需要IO&#xff1f; java在1.4之前&#xff0c;提供的是BIO&#xff0c;也就是java.io包下的的东西&#xf…

SpringBoot(二):配置文件的作用、配置文件的格式、properties配置文件、yml配置文件

目录一、配置文件的作用二、配置文件的格式三、properties配置文件3.1 properties的基本语法3.2 properties的缺点3.3 配置自定义内容3.4 读取配置文件四、yml配置文件4.1 yml基本介绍4.2 yml基本语法4.3 使用yml配置不同的数据类型4.4 读取yml配置文件4.5 在yml中配置对象4.6 …

关于UWB汽车钥匙介绍

汽车钥匙经历了机械钥匙、遥控钥匙、PEPS、数字钥匙四个阶段&#xff0c;而数字钥匙又分为BLE/NFC/UWB三种技术路线。由于UWB安全性、定位精度、作用范围明显好于BLE和NFC&#xff0c;因此成为汽车数字钥匙的最优技术。PEPS与数字钥匙PEPS是指无钥匙进入/无钥匙启动系统&#x…