线程的使用1

news2025/1/10 2:23:00

1. 创建一个线程

1.1 创建线程练习

线程实际上是应用层的概念,在 Linux 内核中,所有的调度实体都被称为任务 (task) ,

他们之间的区别是:有些任务自己拥有一套完整的资源,而有些任务彼此之间共享一套资源

对此函数的使用需要知道以下几点:

1,线程例程指的是:如果线程创建成功,那么该线程会立即去执行的函数。

2,POSIX 线程库的所有 API 对返回值的处理原则都是一致的:成功返回 0,失败返回 错误码 errno。

3 ,线程属性如果为 NULL,则会创建一个标准属性的线程,线程的属性非常多,下面 是关于线程属性的详细讨论。

跟线程属性有关的 API 有:

thread1.c

#include <stdio.h>
#include <pthread.h>

//回调函数
void *xiancheng (void *argc)
{
    int i=0;
    while (1)
    {
        printf("%d\n",i);
        i++;
        sleep(1);
    }
    
}

int main()
{
    pthread_t tid;
    //创建一个线程
    pthread_create(&tid,NULL,&xiancheng,NULL);

    pause();//停留在此
    
}

成功

1.2 退出线程

线程跟进程类似,在缺省的状态下退出之后,会变成僵尸线程,并且保留退出值。其他 线程可以通过相关 API 接合该线程——使其资源被系统回收,如果愿意的话还可以顺便获取 其退出值。下面是相关 API:

1.3 接合指定线程

用上述函数需要注意以下几点:

1,如果线程退出时没有退出值,那么 retval 可以指定为 NULL。

2,pthread_join( )指定的线程如果尚在运行,那么他将会阻塞等待。

3,pthread_tryjoin_np( )指定的线程如果尚在运行,那么他将会立即出错返回。

1.4 取消线程请求

另外,或许在某个时刻不能等某个线程“自然死亡”,而需要勒令其马上结束,此时可 以给线程发送一个取消请求,让其中断执行而退出。用到如下 API:

而当线程收到一个取消请求时,他将会如何表现取决于两个东西:一是当前的取消状态, 二是当前的取消类型。线程的取消状态很简单——分别是 PTHREAD_CANCEL_ENABLE 和 PTHREAD_CANCEL_DISABLE,前者是缺省的,代表线程可以接受取消请求,后者代表关闭 取消请求,不对其响应。

而在线程接受取消请求的情况下,如何停下来又取决于两种不同的响应取消请求的策略 ——延时响应和立即响应,当采取延时策略时,线程并不会立即退出,而是要遇到所谓的“取 消点”之后,才退出。而“取消点”,指的是一系列指定的函数。

1.5  分离线程的使用细节

以上API 都是针对线程属性操作的,所谓线程属性是类型为 pthread_attr_t 的变量, 设置一个线程的属性时,通过以上相关的函数接口,将需要的属性添加到该类型变量里 面,再通过 pthread_create( )的第二个参数来创建相应属性的线程。

线程属性变量的使用步骤是:

1,定义线程属性变量,并且使用 pthread_attr_init( )初始化。

2,使用 pthread_attr_setXXX( )来设置相关的属性。

3,使用该线程属性变量创建相应的线程。

4,使用 pthread_attr_destroy( )销毁该线程属性变量。

线程的属性很多,其中着重关注的几个属性 API 是:

一条线程如果是可接合的,意味着这条线程在退出时不会自动释放自身资源,而会成为 僵尸线程,同时意味着该线程的退出值可以被其他线程获取。因此,如果不需要某条线程的 退出值的话,那么最好将线程设置为分离状态,以保证该线程不会成为僵尸线程。

分离线程在退出时,相关资源会被系统自动回收,而不需要显式调用 pthread_join 函数等待线程结束。

重点

主线程的结束,会导致整个程序的退出结束,那时候任何线程的任何操作都将停止,包括其他线程要输出但是还没来得及输出的情况

thread2.c

#include <stdio.h>
#include <pthread.h>

//分离线程的细节
//重点,主线程的结束,会导致整个程序的退出结束,那时候任何线程的任何操作都将停止,包括其他线程要输出但是还没来得及输出的情况

//回调函数
void *xiancheng (void *argc)
{
    int i=0;
    while (1)
    {
        sleep(1);
        printf("%d\n",i);
        i++;
        if(i>10){
            break;
        }

    }

    //终止线程的函数。它的作用是终止当前线程的执行,并将一个退出状态传递给主线程(或者调用 pthread_join 等待的线程)。
    //但是分离线程拿不到退出状态
    pthread_exit("byebye\n");
    
}

int main()
{
    printf("我创建线程啦\n");
    pthread_t tid1;
    pthread_t tid2;

    void* p1 = NULL;
    void* p2 = NULL;

    //设置分离属性
    //创建属性变量
    pthread_attr_t attr1;
    //初始化属性变量
    pthread_attr_init(&attr1);
    //对这个属性变量,设置分离属性
    pthread_attr_setdetachstate(&attr1,PTHREAD_CREATE_DETACHED);
    
	//把设置好的属性变量attr1,传到创建线程函数中
    //创建一个线程
    pthread_create(&tid1,&attr1,&xiancheng,NULL);//这个线程是分离属性的

    pthread_create(&tid2,NULL,&xiancheng,NULL);//默认创建的线程是可结合的属性

    pthread_join(tid1,&p1);//tid1是分离线程,主线程不需要等待它的执行
    pthread_join(tid2,&p2);//相当于wait,对于分分离线程它会一直等待子线程执行完成

    printf("p1:%s\n",(char*)p1);
    printf("p2:%s\n",(char*)p2); 
}

2. 设置线程调度策略

2.1 nice函数

动态优先级数值越大,优先级越低

nice.c

#include <pthread.h>
#include <stdio.h>
#include <unistd.h>
#include <errno.h>
#include <string.h>

//nice函数


void *a1(void *arg)
{
	char *msg = (char *)arg;//把参数解出来,需要什么类型,按情况解参数

	while(1)
	{
		if(strcmp(msg,"A\0") == 0)
		{
			nice(-19);//给A的亲和度降到最低,cpu会打印他,因为亲和度低
		}
		if(strcmp(msg,"B\0") == 0)
		{
			nice(15);//给B的亲和度升到最高,cpu很少打印他,因为亲和度太高了
		}
		fprintf(stderr, "%c", *msg);
	}
	
}


//分离与接合
int main()
{
	//定义一个线程号tid
	pthread_t tid1;
	pthread_t tid2;
			

	pthread_create(&tid1, NULL, a1, "A");//屌丝线程,静态优先级为0
	
	pthread_create(&tid2, NULL, a1, "B");//屌丝线程,静态优先级为0
	
	pause();
	
}

2.2 静态优先级和调度策略解析

2.2.1 获取、设置线程是否继承创建者的调度策略

2.2.2 获取、设置线程的调度策略

当需要给一个线程设置调度方面的属性时 ,必须先将线程的 inheritsched 设置为 PTHREAD_EXPLICIT_SCHED。

SCHED _FIFO 调度策略为此,通俗讲就是,获得cpu就会一直执行自己直到自己运行结束,才会让出cpu

SCHED  RR 调度策略为此,通俗讲就是 ,每个线程都会获得cpu的时间在获得时间内执行,时间到了换下一个拥有时间的线程执行

前面两个策略有个条件,就是和同批次竞争者的静态优先级一样,如果有的竞争者静态优先级高过它,那就让这个静态优先级高的执行(老师说的高富帅)(就是如果他们的静态优先级一样的话来博弈。)

当线程的调度策略为 SCHED_OTHER 时,其静态优先级 (static priority) 必须设置 为 0 。该调度策略是 Linux 系统调度的默认策略,处于 0 优先级别的这些线程按照所谓的动 态优先级被调度,而动态优先级起始于线程的 nice 值,且每当一个线程已处于就绪态但被 调度器调度无视时,其动态优先级会自动增加一个单位,这样能保证这些线程竞争 CPU 的 公平性。

2.2.3 获取、设置线程静态优先级

1,静态优先级是一个定义如下的结构体:

struct sched_param

{

int sched_priority;

};

set_policy.c
#include <pthread.h>
#include <stdio.h>
#include <unistd.h>
#include <errno.h>
#include <string.h>


//静态优先级和调度策略的探讨

void *a1(void *arg)
{
	char *msg = (char *)arg;//把参数解出来,需要什么类型,按情况解参数

	
	while(1)
	{

		fprintf(stderr, "%c", *msg);
	}
	
}


//分离与接合
int main()
{
	//定义一个线程号tid
	pthread_t tid1;
	pthread_t tid2;
	
	pthread_attr_t attr1;
	pthread_attr_t attr2;
	
	
	//初始化属性变量
	pthread_attr_init(&attr1);
	pthread_attr_init(&attr2);
	
	//选择是否继承创建者的调度策略
	pthread_attr_setinheritsched(&attr1,PTHREAD_EXPLICIT_SCHED);
	
	pthread_attr_setinheritsched(&attr2,PTHREAD_EXPLICIT_SCHED);
	
	//设置线程的调度策略
	// pthread_attr_setschedpolicy(&attr1, SCHED_FIFO);  
	// pthread_attr_setschedpolicy(&attr2, SCHED_FIFO);

	pthread_attr_setschedpolicy(&attr1, SCHED_RR);  
	pthread_attr_setschedpolicy(&attr2, SCHED_RR);
	
	struct sched_param policy;
	
	policy.sched_priority = 20;
	
	//设置静态优先级
	pthread_attr_setschedparam(&attr1,&policy);//只有管理员才能修改线程的静态优先级
	
	// policy.sched_priority = 21;

	pthread_attr_setschedparam(&attr2,&policy);
	

	pthread_create(&tid1, &attr1, a1, "A");//屌丝线程,静态优先级为0
	pthread_create(&tid2, &attr2, a1, "B");//屌丝线程,静态优先级为0
	
	pause();
	
}

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

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

相关文章

机器学习深度学学习分类模型中常用的评价指标总结记录与代码实现说明

在机器学习深度学习算法模型大开发过程中&#xff0c;免不了要对算法模型进行对应的评测分析&#xff0c;这里主要是总结记录分类任务中经常使用到的一些评价指标&#xff0c;并针对性地给出对应的代码实现&#xff0c;方便读者直接移植到自己的项目中。 【混淆矩阵】 混淆矩阵…

多模块下MyBatis官方生成器

MyBatis官方生成器 1. 依赖插件 创建generator模块 在父模块中进行版本管理 <dependency><groupId>org.mybatis</groupId><artifactId>mybatis</artifactId><version>3.5.6</version> </dependency><dependency><g…

Python练习题(三)

&#x1f4d1;前言 本文主要是【Python】——Python练习题的文章&#xff0c;如果有什么需要改进的地方还请大佬指出⛺️ &#x1f3ac;作者简介&#xff1a;大家好&#xff0c;我是听风与他&#x1f947; ☁️博客首页&#xff1a;CSDN主页听风与他 &#x1f304;每日一句&am…

[足式机器人]Part2 Dr. CAN学习笔记-Ch0-1矩阵的导数运算

本文仅供学习使用 本文参考&#xff1a; B站&#xff1a;DR_CAN Dr. CAN学习笔记-Ch0-1矩阵的导数运算 1. 标量向量方程对向量求导&#xff0c;分母布局&#xff0c;分子布局1.1 标量方程对向量的导数1.2 向量方程对向量的导数 2. 案例分析&#xff0c;线性回归3. 矩阵求导的链…

el-pagination 纯前端分页

需求&#xff1a;后端把所有数据都返给前端&#xff0c;前端进行分页渲染。 实现思路&#xff1a;先把数据存储到一个大数组中&#xff0c;然后调用方法进行切割。主要使用数组的slice方法 所有代码&#xff1a; html <template><div style"padding: 20px&qu…

CSS 局限-contain

CSS 局限 CSS 局限规范的目标在于通过允许浏览器从页面的其余部分中隔离出页面子树而改善性能。若浏览器知道页面的某一部分为独立的&#xff0c;则可优化渲染并改善性能。 此外&#xff0c;此规范允许开发者标示元素究竟是否应当渲染其内容&#xff0c;以及在屏外时是否应当…

【程序员 | 交流】程序员情商修炼指南系列 (沟通是有效合作一大利器)

&#x1f935;‍♂️ 个人主页: AI_magician &#x1f4e1;主页地址&#xff1a; 作者简介&#xff1a;CSDN内容合伙人&#xff0c;全栈领域优质创作者。 &#x1f468;‍&#x1f4bb;景愿&#xff1a;旨在于能和更多的热爱计算机的伙伴一起成长&#xff01;&#xff01;&…

如何能够对使用ShaderGraph开发的Shader使用SetTextureOffset和SetTextureScale方法

假设在ShaderGraph中的纹理的引用名称为"_BaseMap"&#xff0c;同时对这个"_BaseMap"纹理使用了采样的节点"SampleTexture2D"&#xff0c;然后该采样节点的uv接入的TilingAndOffset节点&#xff0c;此时的关键步骤是新建一个Vector4属性&#xf…

HT7183 高功率异步升压转换器 中文资料

HT7183是一款高功率异步升压转换器&#xff0c;集成120mΩ功率开关管&#xff0c;为便携式系统提供G效的小尺寸处理方案。HT7183具有2.6V至5.5V输入电压范围&#xff0c;可为各类不同供电的应用提供支持。HT7183具备3A开关电流能力&#xff0c;并且能够提供高达16V的输出电压。…

实时绘画迎来大更新,本地即可部署

个人网站&#xff1a;https://tianfeng.space 前言 自此LCM公布以来&#xff0c;这一个星期在相关应用方面的更新速度nb&#xff0c;各种实时绘画工作流随之出现&#xff0c;之前还只能依赖krea内测资格使用&#xff0c;让我们来看看上周发生了那些事吧&#xff01; 网盘&am…

做外贸如何写开发信?外贸邮件营销怎么写?

外贸业务员写开发信的技巧&#xff1f;撰写客户开发信模板详解&#xff01; 外贸经营是一项竞争激烈的行业&#xff0c;写好开发信是吸引客户、建立合作关系的重要一环。蜂邮EDM将为您详细介绍如何撰写出色的开发信&#xff0c;以吸引客户的眼球&#xff0c;引领他们与您建立联…

YOLOv8独家原创改进:创新自研CPMS注意力,多尺度通道注意力具+多尺度深度可分离卷积空间注意力,全面升级CBAM

💡💡💡本文自研创新改进:自研CPMS, 多尺度通道注意力具+多尺度深度可分离卷积空间注意力,全面升级CBAM 1)作为注意力CPMS使用; 推荐指数:五星 CPMS | 亲测在多个数据集能够实现涨点,对标CBAM。 收录 YOLOv8原创自研 https://blog.csdn.net/m0_63774211/ca…

PTA 6-1 最小生成树(普里姆算法)使用递归

普利姆算法的原理 普里姆算法查找最小生成树的过程&#xff0c;采用了贪心算法的思想。对于包含 N 个顶点的连通网&#xff0c;普里姆算法每次从连通网中找出一个权值最小的边&#xff0c;这样的操作重复 N-1 次&#xff0c;由 N-1 条权值最小的边组成的生成树就是最小生成树。…

HarmonyOS 振动效果开发指导

Vibrator 开发概述 振动器模块服务最大化开放硬工最新马达器件能力&#xff0c;通过拓展原生马达服务实现振动与交互融合设计&#xff0c;打造细腻精致的一体化振动体验和差异化体验&#xff0c;提升用户交互效率和易用性、提升用户体验、增强品牌竞争力。 运作机制 Vibrato…

数据结构与算法-动态查找表

查找 &#x1f388;3动态查找表&#x1f52d;3.1二叉排序树&#x1f3c6;3.1.1二叉排序树的类定义&#x1f3c6;3.1.2二叉排序树的插入和生成&#x1f3c6;3.1.3二叉树的查找&#x1f3c6;3.1.4二叉排序树的删除 &#x1f52d;3.2平衡二叉树&#x1f3c6;3.2.1平衡二叉树的调整…

基于jsp的搜索引擎

摘 要 随着互联网的不断发展和日益普及&#xff0c;网上的信息量在迅速地增长&#xff0c;在2004年4月&#xff0c;全球Web页面的数目已经超过40亿&#xff0c;中国的网页数估计也超过了3亿。 目前人们从网上获得信息的主要工具是浏览器&#xff0c;搜索引擎在网络中占有举足轻…

平价的开放式耳机怎么选?推荐几款平价好用的耳机,亲测对比

是不是也在为如何在有限的预算内找到一款性价比高的开放式耳机而烦恼呢&#xff1f;别着急&#xff0c;小编为你精心挑选了几款平价好用的开放式耳机&#xff0c;并亲自进行了对比测试&#xff0c;在这个音乐时代&#xff0c;不需要花大价钱就能拥有高品质的音乐体验&#xff0…

微积分-圆的面积和周长(1)

微积分 历史 先有牛顿后有天&#xff0c;创世之后再造仙。作为近代物理学的开山鼻祖&#xff0c;牛顿的贡献怎么评价都不为过。而微积分是首先被牛顿搞出来的也已经是公认的事实&#xff0c;牛顿在研究物理问题的时候顺带做出来的&#xff0c;不知是舍不得发表还是不屑于发表…

Jmeter的安装配置,性能测试编写

1、jmeter介绍 Apache JMeter是一款纯java编写负载功能测试和性能测试开源工具软件。相比Loadrunner而言&#xff0c;JMeter小巧轻便且免费&#xff0c;逐渐成为了主流的性能测试工具&#xff0c;是每个测试人员都必须要掌握的工具之一。 运行环境为Windows 10系统&#xff0c…

电动车刷卡-CI522方案

Ci522是一颗工作在13.56MHz频率下的非接触式读写芯片&#xff0c;支持读A卡&#xff08;CI523支持读A/B卡&#xff09;&#xff0c;可做智能门锁、电动车NFC一键启动、玩具NFC开锁等应用。为部分要求低成本&#xff0c;PCB小体积的产品提供了可靠的选择。 Ci522与Si522/MFRC52…