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

news2024/11/28 18:45:07

目录

一、进程间通信机制

管道(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.coloradmin.cn/o/1961457.html

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

相关文章

华杉研发九学习日记20 LinkedHashMap TreeMap Arrays 函数式接口 方法引用

华杉研发九学习日记20 一&#xff0c;LinkedHashMap 与HashMap相比&#xff0c;key是有序的 Map<Integer,String> map new LinkedHashMap<Integer,String>(); map.put(1, "one"); map.put(2, "two"); map.put(3, "three"); map.…

GitHub Desktop commit文件到repository

1. Clone a repository到本地 2. 在本地仓库修改/添加需要提交的文件或者文档 3. 添加comments并commit 4. 提交完成&#xff0c;点击Push origin提交代码到Github远程仓库 上传成功后&#xff0c;刷新Github网站页面就会出现上传的项目

鸿蒙应用框架开发【自绘编辑框】 输入法框架

自绘编辑框 介绍 本示例通过输入法框架实现自会编辑框&#xff0c;可以绑定输入法应用&#xff0c;从输入法应用输入内容&#xff0c;显示和隐藏输入法。 效果预览 使用说明 1.点击编辑框可以绑定并拉起输入法&#xff0c;可以从输入法键盘输入内容到编辑框。 2.可以点击a…

SSM老人服务管理系统小程序-计算机毕业设计源码91022

摘 要 21世纪的今天&#xff0c;随着社会的不断发展与进步&#xff0c;人们对于信息科学化的认识&#xff0c;已由低层次向高层次发展&#xff0c;由原来的感性认识向理性认识提高&#xff0c;管理工作的重要性已逐渐被人们所认识&#xff0c;科学化的管理&#xff0c;使信息存…

跨网段 IP 地址通信故障分析

现如今计算机网络的规模和复杂性不断增加&#xff0c;跨网段通信成为网络运行中的常见需求。但如果设备处于不同网段且路由设置出现偏差时就会导致通信故障&#xff0c;严重影响网络的正常运行和数据传输。 1.跨网段通信的基本原理 跨网段通信依赖于路由器的路由功能。路由器根…

vue3.0 入门基础知识汇总【1】 全面 精简 推荐

这篇博文主要对一些刚入门vue框架的同学&#xff0c;以及对vue基本知识进行巩固的&#xff0c;最后就是精简一下基本知识&#xff0c;以方便自己查看&#xff0c;感谢参考&#xff0c;有问题评论区交流&#xff0c;谢谢。 目录 1.component组件的基本结构和使用 2.method方法…

全网最适合入门的面向对象编程教程:28 类和对象的Python实现-Python编程原则、哲学和规范大汇总

全网最适合入门的面向对象编程教程&#xff1a;28 类和对象的 Python 实现-Python 编程原则、哲学和规范大汇总 摘要&#xff1a; 本文主要介绍了在使用 Python 进行面向对象编程时&#xff0c;Python 异常处理的原则-“请求谅解&#xff0c;而非许可”&#xff0c;以及软件设…

什么是安全编程?

安全编程&#xff08;Secure Programming&#xff09;是一种编程方法论&#xff0c;旨在通过编写安全可靠的代码来保护计算机系统和数据的安全性。它涵盖了软件设计、开发、测试和维护的整个生命周期&#xff0c;旨在最大程度地降低软件漏洞和安全缺陷的风险。以下是对安全编程…

【前端 20】Element-UI快速入门

探索Element UI组件库&#xff1a;快速搭建Vue应用的必备工具 在现代Web开发中&#xff0c;Vue.js以其轻量级和灵活性赢得了广泛的关注。而Element UI&#xff0c;作为Vue.js的一个UI组件库&#xff0c;更是为开发者们提供了丰富、易用的前端组件&#xff0c;极大地加速了开发过…

Spring源码(八)--Spring实例化的策略

Spring实例化的策略有几种 &#xff0c;可以看一下 InstantiationStrategy 相关的类。 UML 结构图 InstantiationStrategy的实现类有 SimpleInstantiationStrategy。 CglibSubclassingInstantiationStrategy 又继承了SimpleInstantiationStrategy。 InstantiationStrategy I…

Java----反射

什么是反射&#xff1f; 反射就是允许对成员变量、成员方法和构造方法的信息进行编程访问。换句话来讲&#xff0c;就是通过反射&#xff0c;我们可以在不需要创建其对象的情况下就可以获取其定义的各种属性值以及方法。常见的应用就是IDEA中的提示功能&#xff0c;当我…

摆弄it:越走越深

在英语中&#xff0c;it是一个单词&#xff0c;就是“它”&#xff0c;这是众所周知的事情。今天&#xff0c;我们就来摆弄一下it&#xff0c;摆弄一下“它”&#xff0c;看看能摆弄出什么名堂来。 一、它是它自己 it 大家都知道&#xff0c;同样&#xff0c;itself&#xff0…

大模型算法面试题(十七)

本系列收纳各种大模型面试题及答案。 1、LoRA权重是否可以合入原模型 LoRA权重可以合入原模型。LoRA&#xff08;Low-Rank Adaptation of Large Language Models&#xff09;是一种用于微调大型语言模型的低秩适应技术。它通过训练低秩矩阵&#xff0c;并将这些参数注入到原始…

onlyoffice用nginx反向代理

我对于onlyoffice的需求就是当个在线编辑器使用。在集成react的时候之前都是写的绝对路径的地址&#xff0c;这样在需要迁移应用的时候就造成了巨大的麻烦&#xff0c;所以我决定用nginx做反向代理&#xff0c;这样我集成的时候就不用每次都修改源码中的地址了。 一开始写的代…

LINUX进程间的通信(IPC)--信号

一、概念 信号通信&#xff0c;其实就是内核向用户空间进程发送信号&#xff0c;只有内核才能发信号&#xff0c;用户空间进程不能发送信号。信号已经是存在内核中的了&#xff0c;不需要用户自己创建。 信号通信的框架 * 信号的发送&#xff08;发送信号进程&#xff09;&am…

阿联酋云手机怎么做TikTok引流?

根据字节跳动广告资源的数据显示&#xff0c;2024年初&#xff0c;TikTok在阿联酋拥有1073万18岁及以上用户&#xff0c;其广告覆盖率达到当地互联网用户群的113%。从2023年初到2024年初&#xff0c;TikTok在阿联酋的潜在广告覆盖率增加了250万&#xff0c;增长率达30.4%。特别…

基于ant-design-vue3多功能操作表格,表头序号为动态添加记录按钮,鼠标在表格记录行,当前行序号显示删除按钮

由于项目需要&#xff0c;并考虑到尽可能让空间利用率高&#xff0c;因此定制开发一个表格组件&#xff0c;组件功能主要是在序号表头位置为添加按钮&#xff0c;点击按钮&#xff0c;新增一行表格数据&#xff1b;表格数据删除不同于以往表格在操作栏定义删除按钮&#xff0c;…

深度学习(概念相关)

深度学习&#xff08;论文相关&#xff09; 深度学习一些概念 通过阅读论文可以理解提取数据特征的重要性 深度学习学习怎么去提取特征 应用领域 深度学习应用&#xff1a; 输入&#xff1a;图像输入或者文字输入 算法&#xff1a;还是基础的模块计算 神经网络中的参数几千…

[JavaScript] 动态获取方法参数名

JavaScript&#xff08;简称“JS”&#xff09;是一种具有函数优先的轻量级&#xff0c;解释型或即时编译型的编程语言。虽然它是作为开发Web页面的脚本语言而出名&#xff0c;但是它也被用到了很多非浏览器环境中&#xff0c;JavaScript基于原型编程、多范式的动态脚本语言&am…

Java导出Excel给每一列设置不同样式示例

Excel导出这里不讲&#xff0c;方法很多&#xff0c;原生的POI可以参照 Java原生POI实现的Excel导入导出&#xff08;简单易懂&#xff09; 这里只说怎么给Excel每一列设置不同的样式&#xff0c;比如下面这样的 直接上代码 Overridepublic void exportTemplate(HttpServletRe…