Linux C 线程间同步机制

news2024/12/28 6:03:53

线程间同步机制

  • 概述
  • 保护机制
    • 互斥锁
      • 创建互斥锁  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[])
{
	//init
	pthread_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.coloradmin.cn/o/1217756.html

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

相关文章

Sentinel规则

一、服务熔断测试 例子: application.properties配置文件 server.port8083spring.application.nameorder#spring.cloud.nacos.discovery.server-addrhttp://192.168.44.64:80spring.cloud.nacos.discovery.server-addrlocalhost:8848spring.cloud.sentinel.transport.port999…

基于单片机的智能家居安保系统(论文+源码)

1.系统设计 本次基于单片机的智能家居安保系统设计&#xff0c;在功能上如下&#xff1a; 1&#xff09;以51单片机为系统控制核心&#xff1b; 2&#xff09;温度传感器、人体红外静释电、烟雾传感器来实现检测目的&#xff1b; 3&#xff09;以GSM模块辅以按键来实现远/近程…

Nginx(四) absolute_redirect、server_name_in_redirect、port_in_redirect 请求重定向指令组合测试

本篇文章主要用来测试absolute_redirect、server_name_in_redirect和port_in_redirect三个指令对Nginx请求重定向的影响&#xff0c;Nginx配置详解请参考另一篇文章 Nginx(三) 配置文件详解 接下来&#xff0c;在Chrome无痕模式下进行测试。 测试1&#xff1a;absolute_redi…

yolov5模型代码怎么修改

yaml配置文件 深度乘积因子 宽度乘积因子 所有版本只有这两个参数的不同&#xff0c;s m l x逐渐加宽加深 各种类型层参数对照 backbone里的各层&#xff0c;在这里解析&#xff0c;只需要改.yaml里的各层参数就能控制网络结构 修改网络结构 第一步&#xff1a;把新加的模块…

用人话讲解深度学习中CUDA,cudatookit,cudnn和pytorch的关系

参考链接 本人学习使用&#xff0c;侵权删谢谢。用人话讲解深度学习中CUDA&#xff0c;cudatookit&#xff0c;cudnn和pytorch的关系 CUDA CUDA是显卡厂商NVIDIA推出的运算平台。 CUDA™是一种由NVIDIA推出的通用并行计算架构&#xff0c;是一种并行计算平台和编程模型&…

在屏幕上打印杨辉三角

我们先来看看杨辉三角长什么样的&#xff1a; 我们一起来看一看它的规则: 1. 每一行的第一个数字和最后一个数字都是1 2. 从第三行开始&#xff0c;中间的数字和最后一个数字等于它上方两个数字之和 我们可以很好的发现下面的数字就是由该数字上面一行和上一列加上该数字的…

redis设置密码

首先到redis的下载目录下&#xff1a;运行 redis-cli 查看redis密码&#xff1a; config get requirepass 设置redis密码为123456&#xff1a; config set requirepass 123456

SQL中的数据类型和规范化,助力数据存储优化

大家好&#xff0c;目前优化数据存储对于获得良好的性能始终至关重要&#xff0c;选择合适的数据类型并应用正确的规范化过程对于决定其性能至关重要。本文将介绍最重要和最常用的数据类型和规范化过程。 一、SQL中的数据类型 SQL中主要有两种数据类型&#xff1a;字符串和数…

【前沿学习】美国零信任架构发展现状与趋势研究

转自&#xff1a;美国零信任架构发展现状与趋势研究 摘要 为了应对日趋严峻的网络安全威胁&#xff0c;美国不断加大对零信任架构的研究和应用。自 2022 年以来&#xff0c;美国发布了多个零信任战略和体系架构文件&#xff0c;开展了多项零信任应用项目。在介绍美国零信任战略…

Numpy数组进阶_Python数据分析与可视化

Numpy数组进阶 Numpy的广播机制高级索引整数数组索引布尔索引花式索引 数组迭代 Numpy的广播机制 广播 (Broadcast) 是 numpy 对不同形状 (shape) 的数组&#xff0c;进行数值计算的方式。 对数组的算术运算通常在相应的元素上进行&#xff0c;当运算中的 2 个数组的形状不同时…

DNS1(Bind软件)

名词解释 1、DNS&#xff08;Domain Name System&#xff09; DNS即域名系统&#xff0c;它是一个分层的分布式数据库&#xff0c;存储着IP地址与主机名的映射 2、域和域名 域为一个标签&#xff0c;而有多个标签域构成的称为域名。例如hostname.example.com&#xff0c;其…

java接收前端easyui datagrid传递的数组参数

这篇文章分享一下怎么在easyui的datagrid刷新表格时&#xff0c;在后端java代码中接收datagrid传递的数组参数。 数组来源于技能的tagbox&#xff08;标签框&#xff09;&#xff0c;tagbox和combobox的区别是tagbox可以选择多项。 标签框渲染的代码为 $("#skill_ids"…

分类预测 | Matlab实现PSO-BiLSTM-Attention粒子群算法优化双向长短期记忆神经网络融合注意力机制多特征分类预测

分类预测 | Matlab实现PSO-BiLSTM-Attention粒子群算法优化双向长短期记忆神经网络融合注意力机制多特征分类预测 目录 分类预测 | Matlab实现PSO-BiLSTM-Attention粒子群算法优化双向长短期记忆神经网络融合注意力机制多特征分类预测分类效果基本描述程序设计参考资料 分类效果…

ubuntu 23.04从源码编译安装rocm运行tensorflow-rocm

因为ubuntu22.04的RDP不支持声音转发&#xff0c;所以下载了ubuntu23.04.但官方的rocm二进制包最高只支持ubuntu22.04&#xff0c;不支持ubuntu 23.04&#xff0c;只能自己从源码编译虽然有网友告诉我可以用docker运行rocm。但是我已经研究了好几天&#xff0c;沉没成本太多&am…

12v24v60v高校同步降压转换芯片推荐

12V/24V/60V 高校同步降压转换芯片推荐&#xff1a; 对于需要高效、稳定、低噪音的降压转换芯片&#xff0c;推荐使用WD5030E和WD5105。这两款芯片都是采用同步整流技术&#xff0c;具有高效率、低噪音、低功耗等优点&#xff0c;适用于各种电子设备。 WD5030E是一款高效率…

一文浅入Springboot+mybatis-plus+actuator+Prometheus+Grafana+Swagger2.9.2开发运维一体化

Swagger是一个规范和完整的框架,用于生成、描述、调用和可视化 RESTFUL风格的Web服务,是非常流行的API表达工具。 Swagger能够自动生成完善的 RESTFUL AP文档,,同时并根据后台代码的修改同步更新,同时提供完整的测试页面来调试API。 Prometheus 是一个开源的服务监控系统和时…

Microsoft发布了一份关于其产品安全修复的 11 月报告。

&#x1f47e; 平均每天有 50 多个漏洞被发现&#xff0c;其中一些会立即被网络犯罪分子利用。我们把那些现在很受网络犯罪分子欢迎&#xff0c;或者根据我们的预测&#xff0c;在不久的将来可能会被大量利用的漏洞称为趋势漏洞。 在攻击者开始利用这些漏洞之前 12 小时&#…

adb手机调试常用命令

查看手机型号 adb shell getprop ro.product.model 查看电池状况 adb shell dumpsys battery 查看分辨率 adb shell wm size 查看屏幕密度 adb shell wm density 查看显示屏参数 adb shell dumpsys window displays 查看android_id adb shell settings get secure android…

flutter web 中嵌入一个html

介绍 flutter web 支持使用 HtmlElementView嵌入html import dart:html; import dart:ui as ui; import package:flutter/cupertino.dart;class WebWidget extends StatelessWidget {const WebWidget({super.key});overrideWidget build(BuildContext context) {DivElement fr…

【二分法】

二分法可以在有序排列中&#xff0c;通过不断对半切割数据&#xff0c;提高数据查找效率。 lst [1,4,6,7,45,66,345,767,788,999] n 66 left 0 right len(lst)-1 while left < right: #边界&#xff0c;当右边比左边还小的时候退出循环 mid (left right)//2 …