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[])
{
	//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;
}

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

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

相关文章

媒体行业的3D建模:在影视中创造特效纹理

在线工具推荐&#xff1a; 三维数字孪生场景工具 - GLTF/GLB在线编辑器 - Three.js AI自动纹理化开发 - YOLO 虚幻合成数据生成器 - 3D模型在线转换 - 3D模型预览图生成服务 在本文中&#xff0c;我们将探讨 3D 建模在媒体行业中的作用&#xff0c;特别是它在影视特效创作…

某60工业互联网安全测试技术学习记录

系列文章目录 文章目录 系列文章目录前言工业互联网安全测试技术安全工具分类常用安全工具介绍 主机安全测试5.1 主机安全测试概览5.2 通用主机安全测试技术主机信息扫描 5.3 Linux主机安全测试5.4 Android 安全测试5.5 Windows主机安全测试5.6 UNIX 主机安全测试 工业渗透测试…

COS对象存储

一. 什么是对象存储 腾讯云叫COS&#xff0c;在阿里云叫OSS&#xff0c;是一样的对象存储&#xff08;Cloud Object Storage&#xff0c;COS&#xff09;是腾讯云提供的一种存储海量文件的分布式存储服务&#xff0c;具有高扩展性、低成本、可靠安全等优点。通过控制台、API、…

【深度学习】吴恩达课程笔记(五)——超参数调试、batch norm、Softmax 回归

笔记为自我总结整理的学习笔记&#xff0c;若有错误欢迎指出哟~ 【吴恩达课程笔记专栏】 【深度学习】吴恩达课程笔记(一)——深度学习概论、神经网络基础 【深度学习】吴恩达课程笔记(二)——浅层神经网络、深层神经网络 【深度学习】吴恩达课程笔记(三)——参数VS超参数、深度…

开源短剧付费变现小程序源码系统+在线开通会员+在线充值 带完整的搭建教程

说起微短剧&#xff0c;相信大家都不会陌生。相比传统网剧冗长的剧情&#xff0c;微短剧最大的看点&#xff0c;是时长短、高浓缩&#xff0c;顺应了当下用户娱乐时间碎片化趋势。其故事题材多为赘婿、霸道总裁、穿越、重生等看似夸张、无厘头&#xff0c;但却非常“上头”的虚…

PyTorch:GPU的使用

在深度学习领域&#xff0c;神经网络模型训练所需的计算量巨大&#xff0c;这就对计算资源提出了高要求。为了处理这一问题&#xff0c;图形处理器&#xff08;GPU&#xff09;被引入到深度学习中&#xff0c;其并行计算能力可以极大加速神经网络的训练过程。PyTorch作为一款出…

什么是脏读、不可重复读、幻读讲解

数据库隔离级别是数据库管理系统中一个重要的概念&#xff0c;它定义了事务之间的可见性和影响。在多用户并发访问数据库时&#xff0c;隔离级别能够确保事务之间的相互独立性&#xff0c;避免数据不一致的问题。本文将深入探讨三种常见的并发问题&#xff1a;脏读、不可重复读…

Java8Stream快速使用

将List集合存入流中 List<String> list new ArrayList<>();list.add("张一");list.add("张二");list.add("张三");list.add("李四");list.add("赵五");list.add("张六");list.add("王八"…

Android---Gradle 构建问题解析

想必做 Android App 开发的对 Gradle 都不太陌生。因为有 Android Studio 的帮助&#xff0c;Android 工程师使用 Gradle 的门槛不算太高&#xff0c;基本的配置都大同小异。只要在 Android Studio 默认生成的 build.gradle 中稍加修改&#xff0c;就都能满足项目要求。但是&am…

为什么红帽Linux值得学习?红帽Linux是什么

为什么红帽Linux值得学习 物联网、云计算、大数据&#xff0c;或许你都耳熟能详&#xff0c;但是Linux可能你却感觉到有点陌生。这些未来趋势的行业使用的嵌入式、c、JAVA、PHP等底层应用软件都是在Linux操作系统上Linux运维工程师作为移动互联网的关键支撑岗位&#xff0c;缺口…

朝夕光年「红砖」搭建平台架构设计和应用落地

在游戏产品的生命周期中&#xff0c;游戏运营需要实现各类营销活动&#xff0c;通过 Native 和 H5 页面&#xff0c;投放到游戏端内和各种社交媒体&#xff0c;实现“拉新&#xff0c;促活&#xff0c;回流&#xff0c;付费”等核心目标。然而&#xff0c;一个游戏一生可能需要…

企业工商四要素核验API的实现原理和功能介绍

引言 随着社会经济的不断发展&#xff0c;对企业信息的准确性和可信度要求也越来越高。为了有效防范企业信息不实和欺诈行为&#xff0c;企业工商四要素核验API应运而生。该API可以通过传入企业名称、社会统一信用代码、法人名称、法人身份证等信息&#xff0c;快速进行核验&a…

JVM虚拟机-虚拟机执行子系统-第6章 字节码指令

字节码指令 Java虚拟机的指令由一个字节长度的、代表着某种特定操作含义的数字&#xff08;称为操作码&#xff0c;Opcode&#xff09;以及跟随其后的零至多个代表此操作所需的参数&#xff08;称为操作数&#xff0c;Operand&#xff09;构成。 字节码与数据类型 在Java虚拟…

小程序action-sheet结合自定义tabbar显示

要实现此效果&#xff0c;遇到的问题&#xff1a;背景在电脑端调试的情况正常的情况下&#xff0c;手机端点击事件工单&#xff0c;返回回来的时候action-sheet卡住在屏幕上&#xff0c;点击遮罩层都不消失。更奇怪的是 这种情况并不是每次发生&#xff0c;而是有时候发生&…

SQLSERVER 遍历循环的两种方式很详细有源码(2)

2.游标循环 Create table WS_Student ( [Id] int primary key not null, [My_Cocode] [int], [My_SCocode] [int], [userId] [bigint], [SetCName] [varchar](50) NULL, [SetEName] [varchar](50) NULL, [SetPcode] [varchar](50) NULL, [Se…

经典/启发式/改进启发式算法应用于机器人路径规划

路径规划是移动机器人导航规划中的一个十分重要且关键的研究课题。 移动的机器人总是在动态、复杂和不可控的环境中工作&#xff0c;比如对核电站的检查和变电站的检查。然而&#xff0c;复杂的动态工作环境要求移动的机器人能够调整其运动路线&#xff0c;以自主完成任务。使…

流媒体协议

◆ RTP(Real-time Transport Protocol)&#xff0c;实时传输协议。 ◆ RTCP(Real-time Transport Control Protocol)&#xff0c;实时传输控制协议。 ◆ RTSP(Real Time Streaming Protocol)&#xff0c;实时流协议。 ◆ RTMP(Real Time Messaging Protocol)&#xff0c;实时…

【论文解读】GPT Understands, Too

一.论文 1.1 P-tuning 区别于之前的工作&#xff0c;这篇工作认为promote可以在句子中的任意位置起到作用&#xff0c;可以将它们插入上下文或目标中 上图中&#xff0c;左图是不使用任何操作&#xff0c;右图是选择在居首和目标前插入promote的embedding&#xff0c;插入pro…

2023最新软件测试20个基础面试题及答案

什么是软件测试&#xff1f; 答案&#xff1a;软件测试是指在预定的环境中运行程序&#xff0c;为了发现软件存在的错误、缺陷以及其他不符合要求的行为的过程。 软件测试的目的是什么&#xff1f; 答案&#xff1a;软件测试的主要目的是保证软件的质量&#xff0c;并尽可能大…

打破内卷宿命,电商只能出海,必须出海!

历史社会学家黄宗智把中国华北小农经济中的“过密化增长”、边际收益递减等现象称之为“内卷”&#xff1a;即在有限空间内的激烈零和式竞争现象&#xff1b;内卷产生的根源是有限且封闭的空间&#xff0c;竞争规则是“排他性”的零和博弈。 空间有限下的零和博弈&#xff0c;正…