进程间通信与线程间通信的方法汇总

目录

一、进程间通信机制

管道(pipe):

命名管道(FIFO):

消息队列(MQ):

信号量(semaphore):

共享内存(shared memory):

信号(signal):

内存映射(mapped memory):

内存映射和共享内存的区别

Socket:

二、线程间通信与同步机制

Linux平台下:

信号(Signal):

锁机制:

条件变量(Condition Variable):

信号量(Semaphore):

Windows平台下:

全局变量:

Message 消息机制:

CEvent 对象:

为什么Linux和Windows的线程通信的实现方式完全不同呢?


无论进程还是线程,通信的本质都是让不同的执行流“看到”同一份资源!!!

一、进程间通信机制

管道(pipe)

管道允许两个有血缘关系的(父子、兄弟等)进程之间的通信。管道是一种半双工的通信方式,数据只能单向流动。例如,父进程向子进程发送数据,或者子进程向父进程发送数据。

原理是通过父子进程的继承关系以及关闭不需要的文件描述符来实现进程间通信

命名管道(FIFO)

类似于管道,但它可以用于任何两个进程之间的通信。通过命令 mkfifo 或系统调用 mkfifo 来创建。例如,在不同用户的进程之间,只要具有适当的权限,就可以通过命名管道进行通信。

命名管道在文件系统中有对应的文件名,在内核中为命名管道维护一个缓冲区,用于存储写入的数据。

消息队列(MQ)

消息队列是消息的连接表,包括 POSIX 消息队列和 System V 消息队列。有足够权限的进程可以向队列中添加消息,被赋予读权限的进程则可以读走队列中的消息。消息队列克服了信号承载信息量少、管道只能传输无格式字节流以及缓冲区大小受限等缺点。

比如,在一个分布式系统中,不同的子系统可以通过消息队列来传递各种类型和规模的数据。

信号量(semaphore)

信号量主要作为进程间以及同进程不同线程之间的同步手段。它可以用于控制对共享资源的访问,确保多个进程或线程不会同时访问和修改共享资源,从而避免冲突和错误。

例如,在一个多线程的数据库操作中,使用信号量来控制对数据库连接的并发访问。

共享内存(shared memory)

共享内存允许多个进程直接访问同一块物理内存区域,避免了数据在不同进程之间的复制和传输开销,是最快的可用 IPC 形式。这是针对其他通信机制运行效率较低而设计的。它往往与其他通信机制,如信号量结合使用,以达到进程间的同步及互斥。

比如,在一个高性能计算的场景中,多个进程需要频繁地交换大量数据,共享内存可以极大地提高通信效率。

信号(signal)

信号是比较复杂的通信方式,用于通知接收进程有某种事情发生。除了用于进程间通信外,进程还可以发送信号给进程本身。

例如,当一个进程出现错误或异常情况时,可以向其他相关进程发送信号,以便它们采取相应的处理措施。

内存映射(mapped memory)

内存映射允许任何多个进程间通信,每一个使用该机制的进程通过把一个共享的文件或内存区域映射到自己的进程地址空间来实现它,它也是一种相比于其他方式而言很快的通信方式。

比如,多个进程可以同时映射同一个大文件,从而实现对文件内容的快速访问和处理。

在 Windows 中,内存映射文件(Memory-Mapped Files)提供了类似于内存映射的功能,允许进程将文件或一块内存区域映射到其地址空间。

内存映射和共享内存的区别

内存映射和共享内存都是进程间通信的有效方式,但它们在实现和应用上存在一些区别:

实现方式

  • 内存映射:通过将文件或特定的内存区域映射到进程的地址空间来实现通信。可以是基于文件的内存映射,也可以是匿名的内存映射。
  • 共享内存:专门在操作系统内核中创建一块可供多个进程共同访问的内存区域。

数据来源

  • 内存映射:数据通常来源于文件。
  • 共享内存:数据可以由进程自行初始化和填充。

同步机制

  • 内存映射:依赖于文件的同步机制,例如文件锁。
  • 共享内存:通常需要额外的同步机制,如信号量,来协调多个进程对共享内存的访问,以避免数据竞争和不一致。

适用场景

  • 内存映射:适用于需要处理大文件数据、在进程间共享文件内容或对文件进行随机访问的情况。
  • 共享内存:适用于需要快速、高效地在进程间共享大量数据,且对数据的实时性和交互性要求较高的场景。

复杂性

  • 内存映射:相对来说实现较为简单,特别是基于文件的映射。
  • 共享内存:需要更复杂的同步策略来保证数据的一致性和正确性。

例如,在一个图像处理系统中,如果需要在多个进程间共享图像数据,且数据量较大、对速度要求高,可能会选择共享内存,并搭配信号量进行同步;而如果需要在进程间共享一个配置文件的内容,更适合使用内存映射。

Socket

它是更为通用的进程间通信机制,可用于不同机器之间的进程间通信。

例如,在网络环境中,不同主机上的进程可以通过 Socket 进行通信,实现分布式应用的协同工作。

二、线程间通信与同步机制

Linux平台下:

信号(Signal)

信号是 Linux 系统中进程间通信的一种异步方式。它类似于进程间的信号处理,用于通知进程发生了特定的事件或异常情况。例如,当进程收到 SIGINT 信号时,表示用户按下了 Ctrl + C 组合键,进程可以根据预设的信号处理函数来做出相应的反应。

锁机制

  1. 互斥锁(Mutex Lock):确保在同一时刻只有一个线程能够访问被保护的资源,实现了资源的独占访问。
    • 例如,在多线程访问共享数据库连接时,使用互斥锁来保证同一时间只有一个线程能获取和使用该连接。
  2. 读写锁(Read-Write Lock):区分读操作和写操作的锁机制。允许多个线程同时进行读操作,但在写操作时进行独占锁定。
    • 对于一个频繁读取但偶尔修改的数据结构,读写锁可以提高并发性能。
  3. 自旋锁(Spin Lock):线程在获取锁时,如果锁不可用,会持续循环尝试获取,而不是进入阻塞状态。适用于短时间等待且线程切换开销较大的场景。
    • 在多核系统中,处理一些简单的临界区操作时,自旋锁可以避免线程切换的开销。

条件变量(Condition Variable)

条件变量通常与互斥锁配合使用,通过通知的方式解锁。当一个线程等待某个条件满足时,它会被阻塞,直到另一个线程发出通知表示条件已满足。

例如,在生产者-消费者模型中,消费者线程在缓冲区为空时等待条件变量,生产者线程在生产数据后通知条件变量,唤醒消费者线程。

信号量(Semaphore)

包括无名线程信号量和命名线程信号量。信号量用于控制对共享资源的访问数量,确保同时访问的线程或进程数量不超过限制。

比如,限制同时访问打印机的进程数量。

Windows平台下:

全局变量

当需要有多个线程来访问一个全局变量时,通常会在这个全局变量前加上 volatile 声明,以防编译器对此变量进行优化。volatile 关键字告诉编译器每次都从内存中读取变量的值,而不是使用可能的缓存值。

Message 消息机制

常用的 Message 通信的接口主要有两个:PostMessage 和 PostThreadMessage 。

  1. PostMessage :线程向主窗口发送消息。
    • 例如,在一个多线程的图形界面应用中,工作线程可以使用 PostMessage 向主窗口发送更新界面的请求。
  2. PostThreadMessage :任意两个线程之间的通信接口。
    • 比如,在一个后台计算线程和一个数据展示线程之间,可以通过 PostThreadMessage 传递计算结果和控制指令。

CEvent 对象

CEvent 为 MFC 中的一个对象,可以通过对 CEvent 的触发状态进行改变,从而实现线程间的通信和同步,这主要是实现线程直接同步的一种方法。

例如,在一个多线程下载任务中,当下载完成后,设置 CEvent 为触发状态,通知其他等待的线程进行后续处理。

为什么Linux和Windows的线程通信的实现方式完全不同呢?

因为两个系统在内核中对线程的实现方式就是完全不同的:

  • Linux 把线程当作进程来实现,内核并没有准备特别的调度算法或是定义特别的数据结构来表示线程,而是将线程仅仅视为一个与创建进程共享系统分配的资源的进程,每个线程都拥有唯一隶属于自己的 task_struct,所以在内核中,线程看起来更像是一个轻量级进程。
  • Windows 则专门设计了支持内核线程的机制,它在每个 task_struct 内为每个内核级线程提供了 tcb 控制块,每个 tcb 用于描述自己的独立的资源,并且支持创建核心级线程来并行执行某一个进程的多个核心级线程。

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

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

相关文章

NFTScan 正式上线 ERC404 浏览器和 NFT API 数据服务

近日,NFTScan 团队正式对外发布了 ERC404 浏览器,将为 ERC404 生态的 NFT 开发者和用户提供简洁高效的 NFT 数据搜索查询服务。NFTScan 作为全球领先的 NFT 数据基础设施服务商,帮助用户更方便地访问和分析 ERC404 相关的 NFT 数据&#xff0…

git使用总结

概述 简介 Git是一种代码托管技术,很多代码托管平台也是基于Git来实现的。 Git可以帮我们做到很多的事情,比如代码的版本控制,分支管理等。 网址 git官网:https://git-scm.com/ 版本控制系统【VCS】 可以完整保存项目的快照&#…

力扣Hot100-543二叉树的直径

给你一棵二叉树的根节点,返回该树的 直径 。 二叉树的 直径 是指树中任意两个节点之间最长路径的 长度 。这条路径可能经过也可能不经过根节点 root 。 两节点之间路径的 长度 由它们之间边数表示。 示例 1: 输入:root [1,2,3,4,5] 输出&a…

【Vue】权限控制

权限管理 分类: 页面权限功能(按钮)权限接口权限 vue3-element-admin 的实现方案 一般我们在业务中将 路由可以分为两种,constantRoutes 和 asyncRoutes。 constantRoutes: 代表那些不需要动态判断权限的路由,如登录页、404(或…

Skywalking 入门与实战

一 什么是 Skywalking? Skywalking 时一个开源的分布式追踪系统,用于检测、诊断和优化分布式系统的功能。它可以帮助开发者和运维人员深入了解分布式系统中各个组件之间的调用关系、性能瓶颈以及异常情况,从而提供系统级的性能优化和故障排查。 1.1 为…

嵌入式初学-C语言-八

#接嵌入式初学-C语言-七# 分支结构 分支结构&#xff1a;又被称之为选择结构 选择结构的形式 多分支 语法&#xff1a; if(条件1) { 语句1; } else if(条件2) { 语句2; } ... else { 语句n1; }案例&#xff1a; #include <stdio.h> int main() { // 需求&#xff…

Apache、nginx

一、Web 1、概述 Web&#xff1a;为⽤户提供的⼀种在互联⽹上浏览信息的服务&#xff0c;Web 服务是动态的、可交互的、跨平台的和图形化的。 Web 服务为⽤户提供各种互联⽹服务&#xff0c;这些服务包括信息浏览服务&#xff0c;以及各种交互式服务&#xff0c;包括聊天、购物…

线程的同步互斥

互斥 互斥保证了在一个时间内只有一个线程访问一个资源。 先看一段代码&#xff1a;三个线程同时对全局变量val进行--&#xff0c;同时val每自减一次其线程局部存储的全局变量 #include <iostream> #include <thread> #include <vector> #include <uni…

Stable Diffusion WebUI本地环境搭建

一、项目代码下载 git clone https://github.com/AUTOMATIC1111/stable-diffusion-webui 二、环境配置 conda create --n stafu python3.10.6 实际上跟自己创建的环境没有关系&#xff0c;项目启动会自动复制这个环境&#xff0c;之后项目根据这个基础环境构建 也可以在自己…

C++高性能通信:图形简述高性能中间件Iceoryx

文章目录 1. 概述2. 支持一个发布者多个订阅者2.2 Iceoryx为何不支持多个发布者发布到同一个主题 3. Iceoryx的架构和数据传输示意图3.1 发布者与订阅者的通信机制3.2 零拷贝共享内存通信机制 4. 使用事件驱动机制4.1 WaitSet机制4.2 Listener机制 5. 已知限制6. 参考 1. 概述 …

ImportError: /lib64/libstdc++.so.6: version `GLIBCXX_3.4.20‘ 报错解决办法

1.查找 libstdc.so.6* find / -name libstdc.so.6*2.copy一个libstdc.so.6.0.19到/usr/lib64/下 cp /usr/lib64/libstdc.so.6 /usr/lib64/3.创建软连接 ln -sf /usr/lib64/libstdc.so.6.0.31 /usr/lib64/libstdc.so.6完毕&#xff01;

中电金信:云原生时代IT基础设施管理利器——基础设施即代码(IaC)

在数字化转型、零售业务快速发展、信创建设驱动下&#xff0c;应用架构、技术架构、基础架构都已向云原生快速演进&#xff0c;银行业IT基础设施管理产生了非常大的变化&#xff0c;当前银行业&#xff0c;正在开展新一轮的核心应用系统重构、基础平台统一建设等重点任务&#…

Linux网络:传输层协议TCP(二)三次挥手四次握手详解

目录 一、TCP的连接管理机制 1.1三次握手 1.2四次挥手 二、理解 TIME_WAIT 状态 2.1解决TIME_WAIT 状态引起的 bind 失败的方法 三、理解CLOSE_WAIT状态 一、TCP的连接管理机制 在正常情况下, TCP 要经过三次握手建立连接, 四次挥手断开连接 1.1三次握手 三次握手顾名思…

【设计模式】代理模式详解

1.简介 代理模式是常用的Java设计模式&#xff0c;该模式的特点是代理类与委托类共享相同的接口。代理类主要负责预处理消息、过滤消息、将消息转发给委托类&#xff0c;并在事后处理消息等。代理类与委托类之间通常存在关联关系&#xff0c;一个代理类对象与一个委托类对象关…

SpringBoot Mysql->达梦8 activiti6.0.0 项目迁移

全部源码&#xff1a;公众号搜索资小库&#xff0c;回复dm获取源码 1.整合达梦 1.1 达梦驱动下载 MyBatis-Plus 框架 | 达梦技术文档 (dameng.com) 1.2 数据迁移 怎么安装数据库&#xff0c;很多大佬有帖子&#xff0c;搜一下达梦先建立用户&#xff0c;使用DM管理工具 链…

SQL Server 数据误删的恢复

在日常的数据库管理中&#xff0c;数据的误删操作是难以避免的。为了确保数据的安全性和完整性&#xff0c;我们必须采取一些措施来进行数据的备份和恢复。本文将详细介绍如何在 SQL Server 中进行数据的备份和恢复操作&#xff0c;特别是在发生数据误删的情况下。假设我们已经…

使用visual studio编译C++项目时无法找到 enum中的某些项

vs 2017 编译一个cocos2dx 的老项目时&#xff0c;报错&#xff1a; 在项目中搜索关键字 ARMATURE_LOOP_COMPLETE&#xff0c;发现在文件EventType.h中是有定义的&#xff0c;是 enum Event 的一项&#xff0c;而且确认了报错的文件已经引入了这个头文件&#xff1a; 这太奇怪了…

傻瓜式PHP-Webshell免杀学习手册,零基础小白也能看懂

项目描述 一、PHP相关资料 PHP官方手册&#xff1a; https://www.php.net/manual/zh/ PHP函数参考&#xff1a; https://www.php.net/manual/zh/funcref.php 菜鸟教程&#xff1a; https://www.runoob.com/php/php-tutorial.html w3school&#xff1a; https://www.w3school…

【React】全面解析:从基础知识到高级应用,掌握现代Web开发利器

文章目录 一、React 的基础知识1. 什么是 React&#xff1f;2. React 的基本概念3. 基本示例 二、React 的进阶概念1. 状态&#xff08;State&#xff09;和属性&#xff08;Props&#xff09;2. 生命周期方法&#xff08;Lifecycle Methods&#xff09;3. 钩子&#xff08;Hoo…

Spring Cloud微服务项目统一封装数据响应体

在微服务架构下&#xff0c;处理服务之间的通信和数据一致性是一个重要的挑战。为了提高开发效率、保证数据的一致性及简化前端开发&#xff0c;统一封装数据响应体是一种非常有效的实践。本文博主将介绍如何在 Spring Cloud 微服务项目中统一封装数据响应体&#xff0c;并分享…