Linux线程属性与多线程开发:API详解与实战代码解析

Linux 线程的属性 线程池 多线程的创建

线程的属性

引入

我们设想一个场景,使用pthread_detach时,发现线程早就已经结束了,这时候pthread_detach还能正常发挥清理线程的 独有空间 的作用吗?

答案是可以的,但是这难免是一个 程序设计上的一个小缺陷,虽不影响结果,但是总是让人感到困惑。为了解决这一问题,我们可以在 线程属性 中进行对应设置。下面我们来学习一下如何操作线程属性吧!

这里再次提醒,当我们属性设置了detach或者调用了pthread_detach后,就不可以再使用pthread_join函数了。

介绍

typedef struct

{

        int etachstate; //线程的分离状态

        int schedpolicy; //线程调度策略

        struct sched_param schedparam; //线程的调度参数

        int inheritsched; //线程的继承性

        int scope; //线程的作用域

        size_t guardsize; //线程栈末尾的警戒缓冲区大小

        int stackaddr_set; //线程的栈设置

        void* stackaddr; //线程栈的位置

        size_t stacksize; //线程栈的大小

} pthread_attr_t;

可以看到,线程属性是一个结构体,其中包含的成员也有很多,但查看和修改步骤都大同小异,下面我主要向大家展示 分离状态 和 栈 属性的 查看和修改。

线程属性设置API

初始化线程属性函数:

int pthread_attr_init(pthread_attr_t *attr);

函数返回值:

        成功:0

        失败:错误号

销毁线程属性所占用的资源函数:

int pthread_attr_destroy(pthread_attr_t *attr);

函数返回值:

        成功:0

        失败:错误号

设置线程属性,分离or非分离

1 int pthread_attr_setdetachstate(pthread_attr_t *attr, int detachstate);

获取程属性,分离or非分离

1 int pthread_attr_getdetachstate(pthread_attr_t *attr, int *detachstat);

参数:

        attr:已初始化的线程属性

        detachstate: 分离状态

                PTHREAD_CREATE_DETACHED(分离线程)

                PTHREAD_CREATE_JOINABLE(非分离线程)

线程设置的步骤

        1、获取

        2、修改

        3、设置

代码练习

#include <pthread.h>
#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
#define SIZE 128
void *th_fun(void *arg)
{while (1)sleep(1);
}
int main(void)
{pthread_t tid;int err, detachstate, i = 1;pthread_attr_t attr;size_t stacksize;void *stackaddr;// 初始化线程属性pthread_attr_init(&attr);// 设置线程的属性值为分离状态pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED);while (1){stackaddr = malloc(SIZE);if (stackaddr == NULL){perror("malloc");_exit(-1);}stacksize = SIZE;// 将栈的地址 和栈的大小设置到线程属性值里pthread_attr_setstack(&attr, stackaddr, stacksize);// 将上面设置好的线程属性值 赋值到 创建的线程中err = pthread_create(&tid, &attr, th_fun, NULL);if (err != 0){perror("pthread_create");_exit(-1);}printf("%d\n", i++);sleep(1);}pthread_attr_destroy(&attr);return 0;
}
代码运行结果

我们可以看到主线程正常运行,说明子线程,线程已经是 分离状态了。

在这里,我想向大家引入一下进程池的概念。

在上面这个例子中,大家可以看到我是在堆区 为栈 申请的空间,这样的好处是,堆区空间较大可以增加一个进程中最大可容纳的线程数目,但是堆区再大,也会有被用完的时候,并且这里 线程申请的空间你不释放,就永远不会归还给系统,相当于一块空间只是用一次,空间资源利用率较低,因此为了提高线程的最大容纳数目和提高空间利用率,线程池就这样诞生了:

线程池

这里我简单提一下,大家心里有数就行:

我们把在一个区域内,存放着多个线程,我们可以从这个里取线程,但用完需要归还,这样当我们取和还的数目近似时,几乎就可以无限使用;而不是像现在一样用了不还,只能等到线程回收。并且这个区域还有一个功能是会根据你的任务数量变化去设置区域中的线程的数目。而这个区域就是线程池。

线程池我之后会详细介绍,这里大家只需知道这个概念即可。

多线程案例

需要实现的功能

输入线程名,该与线程执行的时间。对应的线程就会执行对应时间长度,并且可以在线程运行期间,加入其他线程,多个线程一起运行。

#include <pthread.h>
#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
#include <string.h>
typedef struct
{char task_name[32];int time;
} MSG;void *deal_fun(void *arg)
{MSG msg = *(MSG *)arg;int i = 0;for (i = msg.time; i > 0; i--){printf("%s剩余时间%d\n", msg.task_name, i);sleep(1);}return NULL;
}
int main(int argc, char const *argv[])
{while (1){MSG msg;printf("输入新增的任务名:");fgets(msg.task_name, sizeof(msg.task_name), stdin);msg.task_name[strlen(msg.task_name) - 1] = 0;printf("输入运行时间:");scanf("%d", &msg.time);getchar(); // 获取换行符pthread_t tid;pthread_create(&tid, NULL, deal_fun, (void *)&msg);pthread_detach(tid); // 线程分离}return 0;
}

代码运行结果

结束

代码重在练习!

代码重在练习!

代码重在练习!

今天的分享就到此结束了,希望对你有所帮助,如果你喜欢我的分享,请点赞收藏夹关注,谢谢大家!!!

博客内容源自课堂笔记,因此偏向于教学,适合新人学习 和 大佬复习,感谢你的阅读!

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

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

相关文章

测试第二课-------测试分类

作者前言 &#x1f382; ✨✨✨✨✨✨&#x1f367;&#x1f367;&#x1f367;&#x1f367;&#x1f367;&#x1f367;&#x1f367;&#x1f382; ​&#x1f382; 作者介绍&#xff1a; &#x1f382;&#x1f382; &#x1f382; &#x1f389;&#x1f389;&#x1f389…

MySQL安装实战分享

一、在 Windows 上安装 MySQL 1. 下载 MySQL 安装包 访问 MySQL 官方下载页面。选择适合你操作系统的版本。一般推荐下载 MySQL Installer。 2. 运行安装程序 双击下载的安装文件&#xff08;例如 mysql-installer-community-<version>.msi&#xff09;。如果出现安全…

数据库预热

介绍 Database Warm-up &#x1f9e0; 一句话理解 数据库是在应用启动阶段&#xff0c;提前建立数据库连接 或 执行轻量 SQL 操作&#xff0c;从而 加快首个请求的响应速度 的一种优化手段 &#x1f3af; 为什么需要数据库预热&#xff1f; 当 FastAPI 或其他 Web 服务刚启…

SearXNG

SearXNG 什么是 SearXNG &#xff1f;说白了&#xff0c;其实就是一个免费开源的搜索引擎。那为什么要本地安装它呢&#xff1f; 看它官网的解释(翻译)&#xff0c;当然&#xff0c;其中官方也有一篇文档解释了为什么需要部署使用私有示例&#xff1a;为什么使用私有实例&…

js 颜色转换分析

一、十六进制转RGB function hexToRgba(hex) {// 移除 # 字符hex hex.replace(#, );// 处理简写形式如 #fffif (hex.length 3) {hex hex[0] hex[0] hex[1] hex[1] hex[2] hex[2];}// 转换为十进制const r parseInt(hex.substring(0, 2), 16); // 截图前两位&#xff0…

智能资源管理机制-重传机制

一、发送端资源管理的核心机制 1. 滑动窗口&#xff08;Sliding Window&#xff09; 这是TCP协议的核心优化设计&#xff1a; 窗口动态滑动&#xff1a;发送端不需要保留所有已发送的分组&#xff0c;只需维护一个"发送窗口"窗口大小&#xff1a;由接收方通告的接…

基于SSM+Layui毕业设计选题系统源码

项目介绍 基于SSM+Layui毕业设计选题系统源码,可以作为课程设计项目参考,该系统分为三个角色: 管理员:用户管理(对学生和老师的信息进行维护),统计分析(对老师课题情况以及学生选题情况信息进行维护),修改密码 老师:个人信息维护,毕业设计题目管理,报名学生管理…

通过uri获取文件路径手机适配

青铜版本 return contentResolver.query(this, arrayOf(MediaStore.MediaColumns.DATA), null, null).let {if (it?.moveToFirst() true) {val columnIndex it.getColumnIndex(MediaStore.MediaColumns.DATA)val path it.getString(columnIndex)it.close()return path}&quo…

vue模拟扑克效果

vue模拟扑克效果 效果图&#xff1a; step1:C:\Users\wangrusheng\PycharmProjects\untitled18\src\views\Home.vue <template><div class"poker-container"><!-- 使用复合数据对象实现双行显示 --><divv-for"(card, index) in POKER_…

基础数学:图论与信息论

微积分与概率论由此进&#xff1a;基础数学&#xff1a;微积分和概率与统计-CSDN博客 线代与优化理论由此进&#xff1a;基础数学&#xff1a;线性代数与优化理论-CSDN博客 数值分析与离散数学由此进&#xff1a;基础数学&#xff1a;数值分析与离散数学-CSDN博客 四、图论与…

构建智能期货交易策略分析应用:MCP与AI的无缝集成

引言 随着金融科技的快速发展&#xff0c;数据驱动的交易决策已成为期货交易领域的重要趋势。本文将深入探讨一个结合了Model Content Protocol (MCP)和AI技术的期货交易策略分析应用——Futures MCP。该应用不仅提供了丰富的技术分析工具&#xff0c;还通过MCP协议与大型语言…

0x02.Redis 集群的实现原理是什么?

回答重点 Redis 集群&#xff08;Redis cluster&#xff09;是通过多个 Redis 实例组成的&#xff0c;每个主节点实例负责存储部分的数据&#xff0c;并且可以有一个或多个从节点作为备份。 具体是采用哈希槽&#xff08;Hash Slot&#xff09;机制来分配数据&#xff0c;将整…

基本的DOS命令

一.打开CMD方式&#xff1a; winR 输入cmd 开始系统命令提示符 在任意文件夹下&#xff0c;shift&#xff0b;鼠标右击&#xff0c;在此处打开命令 资源管理器的地址栏前面输入cmd 以管理员身份打开cmd&#xff1a;选择以管理员方式运行 二.常用的Dos命令 #盘符切换 盘符…

深度剖析:架构评估的常用方法与应用

架构评估是确保系统架构满足需求、性能和质量等方面要求的重要环节&#xff0c;以下是一些常见的架构评估方法的详细介绍&#xff1a; 一、基于调查问卷或检查表的评估方法 1.方法概述&#xff1a;该方法通过设计一系列针对性的问题或检查项&#xff0c;形成问卷或检查表&…

代码随想录算法训练营第十六天

LeetCode题目: 530. 二叉搜索树的最小绝对差501. 二叉搜索树中的众数236. 二叉树的最近公共祖先3272. 统计好整数的数目(每日一题) 其他: 今日总结 往期打卡 530. 二叉搜索树的最小绝对差 跳转: 530. 二叉搜索树的最小绝对差 学习: 代码随想录公开讲解 问题: 给你一个二叉搜…

基于双闭环PID控制器的永磁同步电机控制系统匝间故障Simulink仿真

欢迎微♥关注“电击小子程高兴的MATLAB小屋”获取巨额优惠 1.模型简介 本仿真模型基于MATLAB/Simulink&#xff08;版本MATLAB 2013Rb&#xff09;软件。建议采用matlab2013 Rb及以上版本打开。&#xff08;若需要其他版本可联系代为转换&#xff0c;高于该版本的matlab均可正…

02-libVLC的视频播放器:播放音视频文件以及网络流

libvlc_new(0, nullptr)功能:创建并初始化libVLC的核心实例,是使用所有libVLC功能的前提。 参数:第一个参数:参数数量(通常设为0)第二个参数:参数列表(通常为nullptr,表示使用默认配置)返回值:成功返回libvlc_instance_t*指针,失败返回nullptr。注意事项:可通过参…

2025蓝桥杯省赛C++B组解题思路

由于题面还没出来&#xff0c;现在先口胡一下思路 填空题直接打表找规律或者乱搞一下就能出&#xff0c;从大题开始说。 1&#xff0c;题意&#xff1a; 给你一个数组&#xff0c;这个数组里有几个数可以被一个连续递增的数字区间求和得出 思路&#xff1a;诈骗题&#xff0c;显…

防止邮件伪造的策略 SPF 介绍

SPF是Sender Policy Framework的缩写&#xff0c;即发件人策略框架&#xff0c;是一种用于防止电子邮件伪造的技术&#xff0c;用来验证发件人邮箱域名的真实性。以下是关于它的详细说明&#xff1a; 1. 定义与作用 SPF是一种电子邮件验证系统&#xff0c;它通过在域名的DNS记…

JavaScript Symbol与BigInt

目录 Symbol类型 一、Symbol 的核心特性 1. 唯一性 2. 不可变性 3. 不可枚举性 二、创建 Symbol 1. 基础创建 2. 全局 Symbol 注册表 三、Symbol 作为对象属性 1. 定义 Symbol 属性 2. 遍历 Symbol 属性 四、内置 Symbol 值 五、实际应用场景 1. 避免属性名冲突 …