Linux C 线程间同步机制

线程间同步机制

  • 概述
  • 保护机制
    • 互斥锁
      • 创建互斥锁  pthread_mutex_init
      • 加锁  pthread_mutex_lock
      • 解锁  pthread_mutex_unlock
      • 删除锁  pthread_mutex_destroy
    • 条件变量
      • 创建条件变量  pthread_cond_init
      • 激活条件变量  pthread_cond_signal
      • 等待条件变量  pthread_cond_wait
      • 删除条件变量  pthread_cond_destroy
    • 信号灯
      • 创建信号量  sem_init
      • 信号量加保护  sem_wait
      • 信号量解保护  sem_post
      • 信号量删除  sem_destroy
  • 线程间通信的例子

概述

  同进程内的所有线程共同使用进程的内存空间,并且线程可以在直接应用层完成,因此线程和线程之间的通信使用“全局变量”即可完成通信。但是由于 Linux 系统没有数据保护方式,所在在线程通信的时候需要进行数据的“同步保护”。
  在同进程中的多个线程都要操作的数据进行保护时,只允许一个线程操作要保护的内容。Linux 系统使用“信号量”、“互斥锁”以及“条件变量”来实现数据同步保护。实现数据保护的流程为:
①创建一种使用的保护机制(信号量、互斥锁或条件变量)。
②在操作保护内容之前,加保护(一旦本线程加保护成功,其他线程在操作就会阻塞)。
③在操作保护内容后,解保护(其他线程自动取消阻塞)。
④删除保护机制。
注:线程间的数据保护机制是一种人为的约束,一定要所有线程都要遵循这个操作才会有意义,同时“加保护”、“解保护”操作在一个线程中一定要成对出现。

保护机制

互斥锁

创建互斥锁  pthread_mutex_init

头文件
  #include <pthread.h>
函数原型:int pthread_mutex_init(pthread_mutex_t *restrict mutex,const pthread_mutexattr_t *restrict attr);
参数介绍:
  mutex:互斥锁编号。
  attr:互斥锁的属性。
在这里插入图片描述
返回值:成功返回 0,失败返回-1,并且设置 errno 变量来指示错误的发生。

	pthread_mutex_t mutexid;pthread_mutex_init(&mutexid,NULL);

加锁  pthread_mutex_lock

头文件
  #include <pthread.h>
函数原型:int pthread_mutex_lock(pthread_mutex_t *mutex);
参数介绍:
  mutex:互斥锁编号。
返回值:成功返回 0,失败返回-1,并且设置 errno 变量来指示错误的发生。

	pthread_mutex_lock(&mutexid);

解锁  pthread_mutex_unlock

头文件
  #include <pthread.h>
函数原型:int pthread_mutex_unlock(pthread_mutex_t *mutex);
参数介绍:
  mutex:互斥锁编号。
返回值:成功返回 0,失败返回-1,并且设置 errno 变量来指示错误的发生。
返回值:

	pthread_mutex_unlock(&mutexid);

删除锁  pthread_mutex_destroy

头文件
  #include <pthread.h>
函数原型:int pthread_mutex_destroy(pthread_mutex_t *mutex)
参数介绍:
  mutex:互斥锁编号。
返回值:成功返回 0,失败返回-1,并且设置 errno 变量来指示错误的发生。
返回值:

	pthread_mutex_destroy(&mutexid);

条件变量

创建条件变量  pthread_cond_init

头文件
  #include <pthread.h>
函数原型:int pthread_cond_init(pthread_cond_t *restrict cond,const pthread_condattr_t *restrict attr);
参数介绍:
  cond:条件变量编号。
  mutex:条件变量的属性。
返回值:成功返回 0,失败返回-1,并且设置 errno 变量来指示错误的发生。

	pthread_cond_t condid;pthread_cond_init(&condid,NULL);

激活条件变量  pthread_cond_signal

头文件
  #include <pthread.h>
函数原型:int pthread_cond_signal(pthread_cond_t *cond);
参数介绍:
  cond:条件变量编号。
返回值:成功返回 0,失败返回-1,并且设置 errno 变量来指示错误的发生。

	pthread_cond_signal(&condid);

等待条件变量  pthread_cond_wait

头文件
  #include <pthread.h>
函数原型:int pthread_cond_wait(pthread_cond_t *restrict cond,pthread_mutex_t *restrict mutex);
参数介绍:
  cond:条件变量编号。
  mutex:条件变量的属性。
返回值:成功返回 0,失败返回-1,并且设置 errno 变量来指示错误的发生。

	pthread_cond_wait(&condid,&mutexid);

删除条件变量  pthread_cond_destroy

头文件
  #include <pthread.h>
函数原型:int pthread_cond_destroy(pthread_cond_t *cond);
参数介绍:
  cond:条件变量编号。
返回值:成功返回 0,失败返回-1,并且设置 errno 变量来指示错误的发生。

	pthread_cond_destroy(&condid);

信号灯

创建信号量  sem_init

头文件
  #include <semaphore.h>
函数原型:==int sem_init(sem_t *sem, int pshared, unsigned int value); ==
参数介绍:
  sem:信号量编号。
  pshared:信号量在作用范围(0:本进程中多个线程共享可用;非 0:在当前登录用户的多个进程之间共享)。
  value:信号量的信号值。
返回值:成功返回 0,失败返回-1,并且设置 errno 变量来指示错误的发生。

	sem_t semid;sem_init(&semid,0, 1);

信号量加保护  sem_wait

头文件
  #include <semaphore.h>
函数原型:int sem_wait(sem_t * sem);
参数介绍:
    sem:信号量编号。
返回值:成功返回 0,失败返回-1,并且设置 errno 变量来指示错误的发生。

	sem_wait(&semid);

信号量解保护  sem_post

头文件
  #include <semaphore.h>
函数原型:int sem_post(sem_t * sem);
参数介绍:
    sem:信号量编号。
返回值:成功返回 0,失败返回-1,并且设置 errno 变量来指示错误的发生。

	sem_post(&semid);

信号量删除  sem_destroy

头文件
  #include <semaphore.h>
函数原型:int sem_destroy(sem_t * sem);
参数介绍:
    sem:信号量编号。
返回值:成功返回 0,失败返回-1,并且设置 errno 变量来指示错误的发生。

	sem_destroy(&semid);

线程间通信的例子

在这里插入图片描述

#include <stdio.h>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <sys/wait.h>
#include <string.h>
#include <fcntl.h>
#include <unistd.h>
#include <errno.h>
#include <sys/types.h>
#include <pthread.h>
#include <semaphore.h>
char path[10];
//信号服务函数
void * son_fun(void * arg)
{int fd2 = open(path,O_RDWR);		//打开读管道while(1){char rb[512] = {0};read(fd2,rb,sizeof(rb));	printf("%s说:%s\n",(char *)arg,rb);	}close(fd2);							//关闭读管道
}
//关于argv:
// 1 是读通道  2 是写通道  3 是自己的信号  4 是发的信号
int main(int argc,char *argv[])
{//initpthread_t id;strcpy(path,argv[2]);//创建管道int val1 = mkfifo(argv[1],0666);int val2 = mkfifo(argv[2],0666);//打开管道int fd1 = open(argv[1],O_RDWR); 		//写管道//创建子线程pthread_create(&id,NULL,son_fun,"he say");//创建子线程//等待写入while(1){char wb[512] = {0};gets(wb);write(fd1,wb,strlen(wb));}close(fd1);pthread_join(id,NULL);return 0;
}

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

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

相关文章

python实现炫酷的屏幕保护程序

shigen日更文章的博客写手&#xff0c;擅长Java、python、vue、shell等编程语言和各种应用程序、脚本的开发。记录成长&#xff0c;分享认知&#xff0c;留住感动。 上次的文章如何实现一个下班倒计时程序的阅读量很高&#xff0c;觉得也很实用酷炫&#xff0c;下边是昨天的体验…

QT5 MSVC2017 64bit配置OpenCV4.5无需编译与示范程序

环境&#xff1a;Windows 10 64位 Opencv版本&#xff1a;4.5 QT&#xff1a;5.14 QT5 MSVC2017配置OpenCV 版本参考&#xff1a; opencv msvc c对应版本 1.安装MSVC2017&#xff08;vs2017&#xff09; 打开Visual Studio Installer&#xff0c;点击修改 选择vs2017生成工…

java使用 TCP 的 Socket API 实现客户端服务器通信

一&#xff1a;什么是 Socket(套接字) Socket 套接字是由系统提供于网络通信的技术, 是基于 TCP/IP 协议的网络通信的基本操作&#xff0c;要进行网络通信, 需要有一个 socket 对象, 一个 socket 对象对应着一个 socket 文件, 这个文件在 网卡上而不是硬盘上, 所以有了 sokcet…

3D应用开发引擎HOOPS如何促进AEC数字化架构革新?

随着科技的不断发展&#xff0c;建筑、工程和施工&#xff08;AEC&#xff09;行业正在掀起令人瞩目的数字化转型浪潮。在这一变革的过程中&#xff0c;Tech Soft 3D的HOOPS SDK&#xff08;软件开发工具包&#xff09;正扮演着关键的角色&#xff0c;为构建世界一流的AEC和BIM…

【CVE-2023-4357】Chrome-XXE 任意文件读取漏洞复现及原理解析

官方文档 https://bugs.chromium.org/p/chromium/issues/detail?id1458911 漏洞描述 Short description: Libxslt is the default XSL library used in WebKit based browsers such as chrome, safari etc. Libxslt allows external entities inside documents that are lo…

UML统一建模语言

UML包含3种构造块&#xff1a;事物、关系、图。 事物&#xff1a;模型中代表性成分的抽象关系&#xff1a;把事物结合在一起图&#xff1a;聚集了相关的事物 事物 结构事务&#xff1a;模型的静态部分&#xff0c;包括类、接口、协作、用例、主动类、构件、制品、结点 行为事…

Shell判断:模式匹配:case(一)

一、前言 shell编程中if和case都是用来做流控的。 二、case语法结构 case 变量 in 模式1&#xff09; 命令序列1 ;; 模式2&#xff09; 命令序列2 ;; 模式3&#xff09; 命令序列3 ;; *) 无匹配…

如何科学的进行Android包体积优化

这篇文章会分享小厂如何做包体积优化相关主题&#xff0c;涉及内容包括&#xff1a;1) Android包体积优化的一种可能是比较标准的推进做法&#xff0c;2) 大致流程的心路历程和思考方式&#xff0c;3) 如何去总结和分享你们进行过的包体积优化项目。本文不仅仅是一篇分享&#…

深入探索 PaddlePaddle 中的计算图

**引言** 计算图是深度学习平台 PaddlePaddle 的核心组件之一&#xff0c;它提供了一种图形化的方式来表示和执行深度学习模型。通过了解和理解 PaddlePaddle 中的计算图&#xff0c;我们可以更好地理解深度学习的工作原理&#xff0c;并且能够更加灵活和高效地构建和训练复杂…

stable diffusion十七种controlnet详细使用方法总结

个人网站&#xff1a;https://tianfeng.space 前言 最近不知道发点什么&#xff0c;做个controlnet 使用方法总结好了&#xff0c;如果你们对所有controlnet用法&#xff0c;可能了解但是有点模糊&#xff0c;希望能对你们有用。 一、SD controlnet 我统一下其他参数&#…

PLC梯形图实操——风扇正反转

文章目录 1.项目内创建函数块&#xff08;FB&#xff09;2.项目内创建数据块&#xff08;DB&#xff09;2.1去除优化块访问2.2去除优化块的访问后对数据块进行编译 3.在函数块&#xff08;FB&#xff09;内实现正转反转的自锁与互锁3.1在函数块内实现电机正反转的梯形图 4.主函…

2 Redis的高级数据结构

1、Bitmaps 首先&#xff0c;最经典的应用场景就是用户日活的统计&#xff0c;比如说签到等。 字段串&#xff1a;“dbydc”&#xff0c;根据对应的ASCII表&#xff0c;最后可以得到对应的二进制&#xff0c;如图所示 一个字符占8位&#xff08;bit&#xff09;&#xff0c;…

HTTP1.1升级HTTP2.0

HTTP1.1升级HTTP2.0 一&#xff0c;前言介绍 1.为什么要升级http2.0 HTTP2.0相比于HTTP1.x有以下几个优点&#xff1a; 二进制分帧&#xff1a;HTTP2.0将所有传输的信息分割为更小的消息和帧&#xff0c;并采用二进制格式对它们进行编码&#xff0c;这样可以更好地对数据进行…

【Rust】快速教程——模块mod与跨文件

前言 道尊&#xff1a;没有办法&#xff0c;你的法力已经消失&#xff0c;我的法力所剩无几&#xff0c;除非咱们重新修行&#xff0c;在这个世界里取得更多法力之后&#xff0c;或许有办法下降。——《拔魔》 \;\\\;\\\; 目录 前言跨文件mod多文件mod 跨文件mod //my_mod.rs…

单机版-redis(手动部署)

单机版-redis部署 部署模式:单机版-redis部署 Redis版本&#xff1a;redis-4.0.1 部署redis方式&#xff1a;手动部署 解决GCC问题 linux升级gcc版本详细教程_gcc升级-CSDN博客 在完成第三步时已完成配置&#xff0c;后续为操作命令以及注意事项&#xff1b; 在进行操作数…

【数据结构】——双链表(增删查改)

目录 前言&#xff1a; 一&#xff1a;双链表的定义 ​编辑 二&#xff1a;双向链表的实现 2.1&#xff1a;链表的构造 2.2&#xff1a;创建头节点 2.3&#xff1a;创建节点 2.4&#xff1a;链表的尾插 2.5&#xff1a;链表的打印 2.6&#xff1a;链表的尾删 2.7&a…

[计算机网络]网络层概述

呼,写了这么久终于重新开始啦! 自己落下了太多东西了.....是时候应该重新拾掇起来了. 关于后面的代码项目,我的想法是vilas.js仍然使用js来进行编写,但是后续其他的项目会开始尝试使用ts来进行书写了. 就算是前端也需要点规范吧..... 0.写在前面 这篇文章要和大家道个歉,首…

2023年中职“网络安全“—Linux系统渗透提权③

2023年中职"网络安全"—Linux系统渗透提权③ Linux系统渗透提权任务环境说明&#xff1a;1. 使用渗透机对服务器信息收集&#xff0c;并将服务器中SSH服务端口号作为flag提交&#xff1b;2. 使用渗透机对服务器信息收集&#xff0c;并将服务器中主机名称作为flag提交…

​软考-高级-系统架构设计师教程(清华第2版)【第13章 层次式架构设计理论与实践(P466~495)-思维导图】​

软考-高级-系统架构设计师教程&#xff08;清华第2版&#xff09;【第13章 层次式架构设计理论与实践&#xff08;P466~495&#xff09;-思维导图】 课本里章节里所有蓝色字体的思维导图

Figma 插件学习(一)

一.插件介绍 插件在文件中运行&#xff0c;执行一个或多个用户操作&#xff0c;并允许用户自定义其体验或创建更高效的工作流程。 插件通过专用插件API与Figma的编辑器交互。还可以利用外部Web API。 1.插件API 插件API支持读写功能&#xff0c;允许查看、创建和修改文件的…