【Operating Systems:Three Easy Pieces 操作系统导论 】第28章 插叙:线程 API

【Operating Systems:Three Easy Pieces 操作系统导论 】
在这里插入图片描述

第28章 插叙:线程 API

pthread 库介绍

线程创建

#include <pthread.h> // 头文件 
int
pthread_create(pthread_t * thread,const pthread_attr_t * attr,void * (*start_routine)(void*),void * arg
);
  • thread 指向 pthread_t 结构类型的指针,我们将利用这个结构与该线程交互,因此需要将它传入 pthread_create(),以便将它初始化。相当于该线程的身份证
  • attr 指定该线程可能具有的任何属性。包括设置栈大小,或关于该线程调度优先级的信息等
  • *start_routine 一个函数指针(function pointer),指向要运行的函数
  • arg要运行的函数的参数

线程完成

通过pthread_join阻塞等待线程完成

pthread_create(&p, NULL, mythread, (void *) 100);  // 通常创建 传入NULL就可以  eg 对于一个int将他打包为参数 不需要
pthread_join(p, (void **) &m);   // 第一个参数是pthread_t 类型  第二个参数是 指针类型   如果不需要返回值 也可以传null

int pthread_mutex_lock(pthread_mutex_t *mutex);
int pthread_mutex_unlock(pthread_mutex_t *mutex);
pthread_mutex_t lock = PTHREAD_MUTEX_INITIALIZER;
// 或是int rc = pthread_mutex_init(&lock, NULL);
pthread_mutex_lock(&lock);
x = x + 1; // or whatever your critical section is
pthread_mutex_unlock(&lock);

创建一个临界区
如果另一个线程确实持有该锁,那么尝试获取该锁的线程将不会从该调用返回(阻塞等待),直到获得该锁

int pthread_mutex_trylock (pthread_mutex_t *mutex);
int pthread_mutex_timedlock (pthread_mutex_t *mutex, struct timespec *abs_timeout); // 避免卡在无期限的获取锁ing

这两个调用用于获取锁(非阻塞获取锁)。如果锁已被占用,则 trylock 版本将失败。获取锁的 timedlock 定版本会在超时或获取锁后返回,以先发生者为准。通常应避免使用这两种版本

条件变量(Condition Variables)

不同于信号量(semaphore),信号量应该是条件变量+互斥锁的组合,见此文
当线程之间必须发生某种信号时,如果一个线程在等待另一个线程继续执行某些操作,条件变量就很有用。

int pthread_cond_wait(pthread_cond_t *cond, pthread_mutex_t *mutex);
int pthread_cond_signal(pthread_cond_t *cond);

要使用条件变量,必须另外有一个与此条件相关的锁。在调用上述任何一个函数时,应该持有这个锁。
第一个函数pthread_cond_wait()使调用线程进入休眠状态,因此等待其他线程发出信号,通常当程序中的某些内容发生变化时,现在正在休眠的线程可能会关心它。典型的用法如下所示:

pthread_mutex_t lock = PTHREAD_MUTEX_INITIALIZER;
pthread_cond_t cond = PTHREAD_COND_INITIALIZER;
pthread_mutex_lock(&lock);
while (ready == 0)pthread_cond_wait(&cond, &lock);
pthread_mutex_unlock(&lock);

唤醒线程的代码运行在另外某个线程中,调用pthread_cond_signal时也需要持有对应锁。像下面这样:

pthread_mutex_lock(&lock);
ready = 1;
pthread_cond_signal(&cond);
pthread_mutex_unlock(&lock);

pthread_cond_wait有第二个参数,因为它会隐式地释放锁,以便在其线程休眠后唤醒线程可以获取锁,之后又会重新获得锁。
本例通过 while 判断 ready 的值的变更,而不是通过条件变量唤醒判断 ready 已变更。将唤醒视为某种事物可能已经发生变化的暗示,而不是绝对的事实,这样更安全

编译和运行

只要main.c 包含 pthread.h 你就成功编译了一个并发程序 。链接时需要 pthread 库,增加 -pthread 标记。

prompt> gcc -o main main.c -Wall -pthread

小结

补充:线程 API 指导
当你使用 POSIX 线程库(或者实际上,任何线程库)来构建多线程程序时,需要记住一些小而重 要的事情:

  • 保持简洁。最重要的一点,线程之间的锁和信号的代码应该尽可能简洁。复杂的线程交互容易产生缺陷。
  • 让线程交互减到最少。尽量减少线程之间的交互。每次交互都应该想清楚,并用验证过的、正确的方法来实现(很多方法会在后续章节中学习)。
  • 初始化锁和条件变量。未初始化的代码有时工作正常,有时失败,会产生奇怪的结果。
  • 检查返回值。当然,任何 C 和 UNIX 的程序,都应该检查返回值,这里也是一样。否则会导致古怪而难以理解的行为,让你尖叫,或者痛苦地揪自己的头发。
  • 注意传给线程的参数和返回值。具体来说,如果传递在栈上分配的变量的引用,可能就是在犯错误。
  • 每个线程都有自己的栈。类似于上一条,记住每一个线程都有自己的栈。因此,线程局部变量应该是线程私有的,其他线程不应该访问。线程之间共享数据,值要在堆(heap)或者其他全局可访问的位置。
  • 线程之间总是通过条件变量发送信号。切记不要用标记变量来同步。
  • 多查手册。尤其是 Linux 的 pthread 手册,有更多的细节、更丰富的内容。请仔细阅读!

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

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

相关文章

【数据结构(四)】栈(1)

文章目录 1. 关于栈的一个实际应用2. 栈的介绍3. 栈的应用场景4. 栈的简单应用4.1. 思路分析4.2. 代码实现 5. 栈的进阶应用(实现综合计算器)5.1. 栈实现一位数计算(中缀表达式)5.1.1. 思路分析5.1.2. 代码实现 5.2. 栈实现多位数计算(中缀表达式)5.2.1. 解决思路5.2.2. 代码实…

Dubbo笔记

一、导包 <!--Dubbo--> <dependency><groupId>org.apache.dubbo</groupId><artifactId>dubbo-spring-boot-starter</artifactId><version>2.7.8</version> </dependency> <!--Zookeeper--> <dependency>&l…

强化学习笔记

这里写自定义目录标题 参考资料基础知识16.3 有模型学习16.3.1 策略评估16.3.2 策略改进16.3.3 策略迭代16.3.3 值迭代 16.4 免模型学习16.4.1 蒙特卡罗强化学习16.4.2 时序差分学习Sarsa算法&#xff1a;同策略算法&#xff08;on-policy&#xff09;&#xff1a;行为策略是目…

Android Studio 安装及使用

&#x1f353; 简介&#xff1a;java系列技术分享(&#x1f449;持续更新中…&#x1f525;) &#x1f353; 初衷:一起学习、一起进步、坚持不懈 &#x1f353; 如果文章内容有误与您的想法不一致,欢迎大家在评论区指正&#x1f64f; &#x1f353; 希望这篇文章对你有所帮助,欢…

设计模式-Factory

定义 工厂设计模式是一种创建型设计模式&#xff0c;它提供了一个用于创建对象的接口&#xff0c;但允许子类决定实例化哪个类。这种设计模式使一个类的实例化延迟到其子类。 实现举例 #include <iostream> #include <string>// 抽象产品类 class Product { pub…

电脑游戏录屏软件,记录游戏高光时刻

电脑游戏录制是游戏爱好者分享游戏乐趣、技巧和成就的绝佳方式&#xff0c;此时&#xff0c;一款好用的录屏软件就显得尤为重要。本文将为大家介绍三款电脑游戏录屏软件&#xff0c;通过对这三款软件的分步骤详细介绍&#xff0c;让大家更加了解它们的特点及使用方法。 电脑游戏…

记一次struct2漏洞获取服务器

文章目录 一、漏洞原因二、漏洞成果三、漏洞利用0x01 struts2漏洞获取shell0x02 todesk配置文件获取连接0x03 orcal数据库连接0x04 web网站 sso管理权限0x05 tomcat网站0x06 获取路由器权限0x07 远程桌面四、总结五、免责声明一、漏洞原因 由于网站使用struct2框架,未及时进行…

视频剪辑技巧:如何高效地将多个视频合并成一个新视频

在视频制作过程中&#xff0c;将多个视频合并成一个新视频是一个常见的操作。这涉及到将多个片段组合在一起&#xff0c;或者将不同的视频素材进行混剪。无论是制作一部完整的影片&#xff0c;还是为社交媒体提供短视频&#xff0c;都要掌握如何高效地将多个视频合并。现在一起…

ky10 server arm 在线编译安装openssl3.1.4

在线编译脚本 #!/bin/shOPENSSLVER3.1.4OPENSSL_Vopenssl versionecho "当前OpenSSL 版本 ${OPENSSL_V}" #------------------------------------------------ #wget https://www.openssl.org/source/openssl-3.1.4.tar.gzecho "安装OpenSSL${OPENSSLVER}...&q…

Nginx配置性能优化的方法

Nginx配置性能优化的方法 在大多数情况下&#xff0c;一个常规安装的Nginx对你的网站来说已经能很好地工作了。然而&#xff0c;如果你真的想挤压出Nginx的性能&#xff0c;你必须更深入一些。在本指南中&#xff0c;我将解释Nginx的那些设置可以微调&#xff0c;以优化处理大…

Joern安装与使用

环境准备 Joern需要在Linux环境中运行&#xff0c;所以在Windows系统中需要借助WSL或虚拟机安装。 JDK安装 Joern的运行需要JAVA环境的支持&#xff0c;本次采用的是JDK17&#xff0c;其他版本建议看一下Joern官方文档。 apt install openjdk-17-jre-headless 配置JAVA环境变…

Win11+Modelsim SE-64 10.6d搭建UVM环境

1、添加源文件及tb文件 在目录下建立文件夹&#xff0c;将DUT和Testbench添加进去&#xff0c;文件夹内容如下所示&#xff1a; 2、以《UVM实战》中的例子做简单的示例&#xff1a; 2.1 设计文件 &#xff1a;dut.sv 功能很简单&#xff0c;即将接受到的数据原封不动发送出去…

UE4基础篇十六:自定义 EQS 生成器

UE4 中的 EQS 带有一组很好的查询项生成器,但在某些情况下,您可能更喜欢根据需要创建生成器。我决定编写自己的生成器,因为我必须编写一个查询来找到查询器周围的最佳位置,但又不能太靠近它。我知道我可以添加一个距离测试来随着距离增加分数,但我什至不想考虑距查询器一定…

python之字符串

字符串常用操作 # 字符串常用方法 s a|b|c|b # 元素是否存在 if a in s:print(yes) # yes # 包含数量 n s.count(b) print(n) # 2 # 字符串切割&#xff0c;返回列表 l s.split(|) # [a, b, c, b] print(l) # 字符串替换 s s.replace(a,A) print(s) # A|b|c|b

vulnhub5

靶机下载地址&#xff1a; https://download.vulnhub.com/boredhackerblog/hard_socnet2.ova 信息收集 第一步信息收集&#xff0c;还是老方法我习惯 fscan 和 nmap 一起用 Fscan 简单探测全局信息 ┌──(kali㉿kali)-[~/Desktop/Tools/fscan] └─$ ./fscan_amd64 -h 19…

5.4 Windows驱动开发:内核通过PEB取进程参数

PEB结构(Process Envirorment Block Structure)其中文名是进程环境块信息&#xff0c;进程环境块内部包含了进程运行的详细参数信息&#xff0c;每一个进程在运行后都会存在一个特有的PEB结构&#xff0c;通过附加进程并遍历这段结构即可得到非常多的有用信息。 在应用层下&am…

轿车5+1汽车变速器变速箱同步器操纵机构机械结构设计CAD汽车工程

wx供重浩&#xff1a;创享日记 对话框发送&#xff1a;汽车变速器 获取完整论文报告说明书工程源文件 变速器工程图 操纵机构3D图 一、机械式变速器的概述及其方案的确定 1.1 变速器的功用和要求 变速器的功用是根据汽车在不同的行驶条件下提出的要求&#xff0c;改变发动机…

JS将一个包含多种字符的数组分类

在JavaScript中&#xff0c;你可以使用数组的reduce()方法将一个包含多种字符的数组分类。reduce()方法会迭代数组的每个元素&#xff0c;并使用一个回调函数将数组缩减为单个值。在回调函数中&#xff0c;你可以根据需要将元素分类。 以下是一个示例代码&#xff0c;将一个包…

仪表盘:pyecharts绘制

一、仪表盘 在数据分析中&#xff0c;仪表盘图&#xff08;dashboard&#xff09;的作用是以一种简洁、图表化的方式呈现数据的关键指标和核心信息&#xff0c;以帮助用户快速理解数据的情况&#xff0c;并从中提取关键见解。 仪表盘图通常由多个图表、指标和指示器组成&…

[羊城杯2020]easyphp .htaccess的利用

[CTF].htaccess的使用技巧总结 例题讲解 掌握知识&#xff1a; 测试发现是阿帕奇服务器&#xff0c;就想到上传文件利用.htaccess配置文件执行jpg文件中的php代码&#xff0c;但是再进行第二次文件写入时会把之前的文件删除掉&#xff0c;所以不能上传两次来利用&#xff0c…