线程的使用1

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

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

【C++】简单的C++程序编译

一、简单的C程序 //prog.cc int main() {return 0; }二、编译 1. win11命令终端 cc prog.cc 2. win11 Visual Studio命令终端 cl /EHsc /W4 prog.cc 3. GNU编译器 g -Wall -o prog prog.cc 三、运行 1.win11 prog 2.Unix/Linux ./prog 四、查看返回值 1.win11 路…

本地存储与复杂数据类型转换

1. 本地存储介绍 2.1 本地存储分类 - localStorage // 存储一个名字localStorage.setItem(uname, abc)// 获取名字console.log(localStorage.getItem(uname));// 删除本地存储 只删名字// localStorage.removeItem(uname)// 改localStorage.setItem(uname, aaa)// 存一个年龄 …

网络运维与网络安全 学习笔记2023.11.30

网络运维与网络安全 学习笔记 第三十一天 今日目标 实现AP自动注册、配置WLAN业务参数、无线终端通过wifi互访 实现AP自动注册 项目背景 企业内网的大量AP已经通过DHCP的方式获得IP地址 为了实现后期大量AP的统一管理&#xff0c;希望通过AC实现集中控制 在AC设备上&#…

企业培训私有化解决方案PlayEdu

本文应网友 林枫 的要求而折腾&#xff1b; 什么是 PlayEdu &#xff1f; PlayEdu 是一款适用于搭建内部培训平台的开源系统&#xff0c;旨在为企业/机构打造自己品牌的内部培训平台。PlayEdu 基于 Java MySQL 开发&#xff1b;采用前后端分离模式&#xff1b;前端采用 React1…

idea保存时自动删除不用的import

1、File->setting 2、Editor->General->Auto Import 按照操作&#xff0c;即可实现&#xff01;&#xff01;&#xff01;&#xff01;&#xff01;&#xff01;&#xff01;

关于开展人工智能专业人员“自然语言及语音处理设计开发工程师”专项培训的通知

“人工智能技术与咨询”发布 工业与信息化部电子工业标准化研究院于2022年7月1日发布《人工智能从业技术人员要求》&#xff0c;现针对已发布标准于1月3日至7日在北京举办《自然语言与语音处理设计开发工程师》中级人才培养&#xff0c;下边是具体文件通知请大家查阅。行业人才…

关于开展人工智能专业人员“计算机视觉处理设计开发工程师”专项培训的通知

“人工智能技术与咨询”发布 工业与信息化部电子工业标准化研究院于2022年7月1日发布《人工智能从业技术人员要求》&#xff0c;现针对已发布标准于1月3日至7日在北京举办《自然语言与语音处理设计开发工程师》中级人才培养&#xff0c;下边是具体文件通知请大家查阅。行业人才…

【c】课程满意度计算

我们不好直接比较二维数组中任意多个元素的值是否相等&#xff0c;我们可以创建一维数组&#xff0c;首先将一维数组的值全部设为0&#xff0c;一维数组的下标代表你喜欢课程的量&#xff0c;一维数组的各个元素的值代表你喜欢的次数 例如 你输入3 5&#xff0c;代表你喜欢第三…

Rust 语言:认识 Rust

本心、输入输出、结果 文章目录 Rust 语言&#xff1a;认识 Rust前言Rust的特点Rust LOGO Rust 在IT行业的应用前景Rust 是一门系统级编程语言相关链接花有重开日&#xff0c;人无再少年实践是检验真理的唯一标准 Rust 语言&#xff1a;认识 Rust 编辑&#xff1a;简简单单 Onl…

线程的使用2

3. 利用管道实现互相的发收通信 jack.c #include<stdio.h> #include<stdlib.h> #include<string.h> #include<unistd.h> #include<sys/types.h> #include<sys/stat.h> #include<fcntl.h> #include <pthread.h>//有名管道进程间…

深圳招聘一般在哪个网站

深圳吉鹿力招聘网是一个专注于深圳招聘的平台&#xff0c;主要提供人才招聘服务。在深圳吉鹿力招聘网上&#xff0c;你可以找到各种深圳招聘信息&#xff0c;包括企业招聘、职位发布、简历投递等。深圳吉鹿力招聘网的出现&#xff0c;方便了求职者的投递和查询工作机会&#xf…

2023年江西省“振兴杯”网络信息行业职业技能竞赛 Web4 Writeup

这次振兴杯碰到的一道题&#xff0c;某些姿势之前貌似没有碰过&#xff0c;简单记一下吧 源码 <?php class Bird{public $funcs;public $salt;public $flag;function say_flag(){$secret hash_hmac(sha256, $_GET[salt], file_get_contents(/flag));$hmac hash_hmac(sha…

开源数据大屏系统介绍

睿思BI数据大屏系统现已开源&#xff0c;通过拖拽配置的方式构建大屏&#xff0c;支持零代码开发。并且包含大量大屏模版&#xff0c;方便用户快速创建大屏应用。 系统主要包括数据准备、大屏设计、权限管理3个部分内容。 1.数据准备 1.1 创建数据源&#xff1a;定义BI系统链…

PHP使用HTTP代码示例模板

PHP是一种广泛用于服务器端的编程语言&#xff0c;它提供了许多内置的函数和扩展&#xff0c;以便开发人员能够轻松地处理HTTP请求和响应。在PHP中&#xff0c;您可以使用以下代码示例模板来处理HTTP请求和生成HTTP响应。 php复制代码 <?php // 处理GET请求 if ($…

计算机组成学习-存储系统总结

复习本章时&#xff0c;思考以下问题&#xff1a; 1)存储器的层次结构主要体现在何处&#xff1f;为何要分这些层次&#xff1f;计算机如何管理这些层次&#xff1f;2)存取周期和存取时间有何区别&#xff1f;3)在虚拟存储器中&#xff0c;页面是设置得大一些好还是设置得小一…

园区无线覆盖方案(智慧园区综合解决方案)

​ 李经理正苦恼头疼的工业园区数字化改造项目。近年企业快速增长,园区内Argent工业设备激增,IT部门应接不暇。为确保生产系统稳定运行,IT管理团队经过反复摸索,决定进行全面的数字化升级。然而改造之艰巨远超想象——混杂的接入环境、复杂的专线部署、长达数月的建设周期,种种…

法律情境扮演、逆向推理文字游戏、AIGC创作……见证AI极致生产力!

飞桨星河社区&#xff0c;以飞桨和文心大模型为核心&#xff0c;集开放数据、开源算法、云端GPU算力及大模型开发工具于一体&#xff0c;在大模型范式下&#xff0c;为开发者提供模型与应用的高效开发环境。在成立的5年以来&#xff0c;已汇集660万AI开发者&#xff0c;覆盖深度…

LLM之RAG实战(一):使用Mistral-7b, LangChain, ChromaDB搭建自己的WEB聊天界面

一、RAG介绍 如何使用没有被LLM训练过的数据来提高LLM性能&#xff1f;检索增强生成&#xff08;RAG&#xff09;是未来的发展方向&#xff0c;下面将解释一下它的含义和实际工作原理。 ​ 假设您有自己的数据集&#xff0c;例如来自公司的文本文档。如何让ChatGPT和其他…

中级工程师评审条件:如何成为一名合格的中级工程师

作为一名工程师&#xff0c;不仅需要具备扎实的技术基础和实践能力&#xff0c;还需要通过评审来证明自己的能力水平。在成为一名合格的中级工程师之前&#xff0c;你需要满足一系列评审条件。甘建二今天将详细介绍中级工程师评审的要求和标准&#xff0c;帮助你成为更优秀的工…

基于java技术的电子商务支撑平台

摘 要 随着网络技术的发展&#xff0c;Internet变成了一种处理日常事务的交互式的环境。互联网上开展各种服务已经成为许多企业和部门的急切需求。Web的普遍使用从根本上改变了人们的生活方式、工作方式&#xff0c;也改变了企业的经营方式和服务方式。人们可以足不出户办理各…