【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 手册,有更多的细节、更丰富的内容。请仔细阅读!

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

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

相关文章

wsl安装ubuntu的问题点、处理及连接

WSL安装Ubuntu的参考链接 (41条消息) wsl报错&#xff1a;WslRegisterDistribution failed with error: 0x800701bc_yzpyzp的博客-CSDN博客_0x800701bc wsl (41条消息) 使用Ubuntu安装软件出现Unable to locate package错误解决办法_大灰狼学编程的博客-CSDN博客 手把手教你…

linux:查看文件前100行和后100行

查看文件中的前100行 head -n 100 文件名查看文件中的后100行 tail -n 100 文件名

【Java 进阶篇】JavaScript JSON 语法入门:轻松理解数据的序列化和反序列化

嗨&#xff0c;亲爱的小白们&#xff01;欢迎来到这篇关于 JavaScript 中 JSON&#xff08;JavaScript Object Notation&#xff09;语法的入门指南。JSON 是一种轻量级的数据交换格式&#xff0c;广泛应用于前端开发中。通过这篇博客&#xff0c;我将带你深入了解 JSON 的语法…

【深度学习实验】注意力机制(四):点积注意力与缩放点积注意力之比较

文章目录 一、实验介绍二、实验环境1. 配置虚拟环境2. 库版本介绍 三、实验内容0. 理论介绍a. 认知神经学中的注意力b. 注意力机制 1. 注意力权重矩阵可视化&#xff08;矩阵热图&#xff09;2. 掩码Softmax 操作3. 打分函数——加性注意力模型3. 打分函数——点积注意力与缩放…

【GUI】-- 12 贪吃蛇小游戏之让小蛇动起来

GUI编程 04 贪吃蛇小游戏 4.3 第三步&#xff1a;让小蛇动起来(键盘控制) 首先&#xff0c;在构造器中要获取焦点事件、键盘监听事件并加入定时器(定时器定义需要实现ActionListener接口并重写actionPerformed方法)&#xff1a; //构造器public GamePanel() {init();this.s…

郎酒“掉队”,经销商们能等来春天吗?

文 | 螳螂观察&#xff08;TanglangFin&#xff09; 作者 | 渡过 有“六朵金花”之称的川酒品牌中&#xff0c;五粮液、泸州老窖、舍得、水井坊都已成功上市&#xff0c;只剩下郎酒和剑南春未上市。 与IPO的“掉队”相对应的&#xff0c;是郎酒在冲刺高端、内部管理、渠道管…

【LeetCode刷题-链表】--23.合并K个升序链表

23.合并K个升序链表 方法&#xff1a;顺序合并 在前面已经知道合并两个升序链表的前提下&#xff0c;用一个变量ans来维护以及合并的链表&#xff0c;第i次循环把第i个链表和ans合并&#xff0c;答案保存到ans中 /*** Definition for singly-linked list.* public class List…

SQL基础理论篇(八):视图

文章目录 简介创建视图修改视图删除视图总结参考文献 简介 视图&#xff0c;即VIEW&#xff0c;是SQL中的一个重要概念&#xff0c;它其实是一种虚拟表(非实体数据表&#xff0c;本身不存储数据)。 视图类似于编程中的函数&#xff0c;也可以理解成是一个访问数据的接口。 从…

VPX 插座(VITA46)介绍及应用 (简单介绍)

1. VPX 插座的介绍 VPX是VITA(VME International Trade Association, VME国际贸易协会)组织于2007年在其VME总线基础上提出的新一代高速串行总线标准。VPX总线的基本规范、机械结构和总线信号等具体内容均在ANSI/VITA46系列技术规范中定义。VPX就是基于高速串行总线的新一代总线…

基于Surfer与Voxler数据处理及可视化实践技术应用

Surfer和Voxler分别是美国Golden Software 公司开发的用于二维和三维数据可视化软件&#xff0c;具有强大的数据处理和插值功能&#xff0c;软件主要应用于气象、环境和地质&#xff08;以及生物、医学等&#xff09;等领域。其中Surfer主要用于绘制二维等值线图、三维表面图以…

仪表盘:pyecharts绘制

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

Java —— String类

目录 1. String类的重要性 2. 常用方法 2.1 字符串构造 2.2 String对象的比较 2.3 字符串查找 2.4 转化 1. 数值和字符串转化 2. 大小写转换 3. 字符串转数组 4. 格式化 2.5 字符串替换 2.6 字符串拆分 2.7 字符串截取 2.8 其他操作方法 2.9 字符串常量池 2.9.1 创建对象的思考…

基于安卓android微信小程序的刷题系统

项目介绍 面试刷题系统的开发过程中&#xff0c;采用B / S架构&#xff0c;主要使用jsp技术进行开发&#xff0c;中间件服务器是Tomcat服务器&#xff0c;使用Mysql数据库和Eclipse开发环境。该面试刷题系统包括会员、答题录入员和管理员。其主要功能包括管理员&#xff1a;个…

芯片IO口不加电阻会怎样?

芯片IO口不加电阻会怎样&#xff1f; 可能会导致以下几个后果&#xff1a; 1.高电流问题&#xff0c;IO口没有电阻限流&#xff0c;当与外部设备直接连接时&#xff0c;就可能会导致过大的电流流过IO口&#xff0c;这就可能损坏IO口&#xff0c;引起短路或烧坏其它电路组件。像…

Spring Boot要如何学习?【云驻共创】

Spring Boot 是由 Pivotal 团队提供的全新框架&#xff0c;其设计目的是用来简化新 Spring 应用的初始搭建以及开发过程。该框架使用了特定的方式来进行配置&#xff0c;从而使开发人员不再需要定义样板化的配置。我这里会分享一些学习Spring Boot的方法和干货&#xff0c;包括…

【C++】泛型编程 ⑨ ( 类模板的运算符重载 - 函数声明 和 函数实现 写在同一个类中 | 类模板 的 外部友元函数问题 )

文章目录 一、类模板 - 函数声明与函数实现分离1、函数声明与函数实现分离2、代码示例 - 函数声明与函数实现分离3、函数声明与函数实现分离 友元函数引入 二、普通类的运算符重载 - 函数声明 和 函数实现 写在同一个类中三、类模板的运算符重载 - 函数声明 和 函数实现 写在同…

Java实现windows系统截图

Java提供了一种方便的方式来截取Windows系统的截图。这个过程通常需要使用Java的Robot类来模拟用户的鼠标和键盘输入操作。下面将介绍如何使用Java实现Windows系统截图。 步骤1&#xff1a;导入Robot和AWT包 Java提供了一个Robot类&#xff0c;它可以模拟用户的键盘和鼠标操作…

医疗器械维修售后技术培训与支持的重要性

医疗器械维修售后技术培训与支持的重要性 随着我国医疗器械产业的的高速发展、医疗器械企业的崛起,大量创新医疗器械产品进入医疗机构。但医疗设备在使用和维护过程中,暴露出许多问题和不足,如部分设备故障率较高、临床工程培训不足、售后服务模式整体比较落后等,这影响了医疗…

当前系统并无桌面环境,或无显示器,无法显示远程桌面,您需要自行安装X11桌面环境,或者使用终端文件功能

ToDesk远程遇到的问题如上图&#xff0c;换向日葵直接黑屏&#xff1b; 问题原因 截止发文时间&#xff0c;Todesk只支持X11协议&#xff0c;没有适配最新的Wayland协议&#xff0c;所以我们需要把窗口系统调整为X11才可以。 解决方法 修改配置文件&#xff0c;关闭wayland su…

c# 文件读取和写入

文件写入 using System.Collections.Generic; namespace demo1;/// <summary> /// System.IO下的所有的Stream类是所有数据流的基类 /// 流是用于传输数据的对象&#xff0c;流就是用来传输数据的 /// 数据传输的两种方式&#xff1a;1、数据从外部源传输到程序中&#…