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

目录

一、进程间通信机制

管道(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://xiahunao.cn/news/3280063.html

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

相关文章

【论文共读】【翻译】【GAN】Generative Adversarial Nets

论文原文地址:https://arxiv.org/pdf/1406.2661 翻译:Generative Adversarial Nets 生成对抗网络 0. 摘要 提出了一种新的对抗过程估计生成模型的框架,其中我们同时训练两个模型:一个是捕获数据分布的生成模型G,另一…

RCE和php文件上传

一、远程命令执行(RCE) RCE漏洞概述 RCE漏洞允许攻击者通过某种方式在目标服务器上执行任意命令。这种漏洞通常出现在服务器端语言中,如PHP。 RCE漏洞原理 PHP中的一些函数可以执行命令或代码,但如果对这些函数的输入未加限制&a…

Docker容器下面home assistant忘记账号密码怎么重置?

环境: docker ha 问题描述: Docker容器下面home assistant忘记账号密码怎么重置? 解决方案: 你可以按照以下步骤来找回或重置密码: 方法一 (未解决) 停止并删除当前的Home Assistant容器(确保你已经保…

【Python工具】Python 实现 telnet、loguru 框架下的 DEBUG 分级日志打印

文章目录 1、背景2、轮子2.1、telnet2.2、loguru DEBUG 日志分级 1、背景 最近业务这边需要用 Python 起一个 web 服务器,做 LLM 相关的业务处理。后台选用的是 django 框架做 web 框架,现在也算结项了。初次写 Python,造出来的轮子啥的总结…

Redis学习[3] ——持久化

四. Redis 持久化 4.1 Redis 如何保证数据不丢失? 由于Redis的数据是保存在内存中,而内存中的数据会在Redis重启后丢失。因此,为了保证数据不丢失,Redis实现了数据持久化的机制。这个机制会将内存中的数据存储到磁盘&#xff0c…

【前端 · 面试 】JavaScript 之你不一定会的基础题(一)

最近我在做前端面试题总结系列,感兴趣的朋友可以添加关注,欢迎指正、交流。 争取每个知识点能够多总结一些,至少要做到在面试时,针对每个知识点都可以侃起来,不至于哑火。 JavaScript 之你不一定会的基础题 前言 面试往…

[LLM]一文学会如何构建属于私有Code Pilot

本文将使用基于Llama.cpp的插件Tabby构建个人Code Pilot助手。 首先我们看一下编码的大模型榜单,在抱抱脸上bigcode上可以参考。 给VSCode插上翅膀 榜单上排名第一的是OpenCodeInterpreter-DS-33B,看起来很强大但是显然 MAC M1 是跑不了。虽然 MAC M1可…

使用人工智能在乳腺癌筛查中的早期影响指标| 文献速递-AI辅助的放射影像疾病诊断

Title 题目 Early Indicators of the Impact of Using AI in Mammography Screening for Breast Cancer 使用人工智能在乳腺癌筛查中的早期影响指标 01 文献速递介绍 基于人群的乳腺癌筛查通过使用乳房X线摄影成功地降低了乳腺癌的死亡率,但这给乳腺放射科医生…

react中路由懒加载

// 1.引入方法,用于创建路由实例 // createBrowserRouter是用于创建history模式 // createHashRouter是用于创建hash模式 // 路由模式的切换只需要更改创建路由实例的方法就行了,其他地方不需要更改 import { createBrowserRouter,createHashRouter } fr…

Navicat For Mysql连接Mysql8.0报错:客户端不支持服务器请求的身份验证协议

windows通过navicat连接本地mysql时报错:Client does not support authentication protocol requested by server; consider upgrading MySQL client 一、问题原因二、解决方法1--失败1. 连接mysql客户端2. 修改加密方式3.正确的解决方法1.查找my.ini文件2.修改my.ini文件3.重…

[C#]基于wpf实现的一百多种音色的Midi键盘软件

键盘 音色库 源码地址:https://download.csdn.net/download/FL1623863129/89599322

NLP与搜广推常见面试问题

1 auc指标 AUC的两种意义 一个是ROC曲线的面积另外一个是统计意义。从统计学角度理解,AUC等于随机挑选一个正样本和负样本时,模型对正样本的预测分数大于负样本的预测分数的概率。下图为搜广推场景下的一个计算auc的例子

开启mybatis-plus日志功能

第一部分:配置文件增添参数 增加如下: configuration:log-impl: org.apache.ibatis.logging.stdout.StdOutImpl 第二部分:运行效果展示

[数据集][目标检测]金属罐缺陷检测数据集VOC+YOLO格式8095张4类别

数据集格式:Pascal VOC格式YOLO格式(不包含分割路径的txt文件,仅仅包含jpg图片以及对应的VOC格式xml文件和yolo格式txt文件) 图片数量(jpg文件个数):8095 标注数量(xml文件个数):8095 标注数量(txt文件个数):8095 标注…

Snowflake 集成模式:Apache Kafka 与零 ETL 和反向 ETL

Snowflake 是领先的云原生数据仓库。集成模式包括批量数据集成、零 ETL 和使用 Apache Kafka 的近乎实时的数据摄取。这篇博文探讨了不同的方法,并发现了它们的利弊。根据行业建议,建议避免使用反向 ETL 等反模式,而是使用数据流来增强企业架…

Vue Router 进阶

Vue Router 通过跳转或取消的方式守卫导航,可以在导航解析的不同节点来控制路由的跳转与取消。定义路由时,可以配置元信息。可以定制页面跳转的过度效果。还可以在程序已经运行的时候添加和删除路由。 1 Router进阶 1.1 导航守卫 守卫,是指…

高品质定制线缆知名智造品牌推荐-精工电联:高压线缆行业定制服务的领航者

定制线缆源头厂家推荐-精工电联:高压线缆行业定制服务的领航者 在当今这个高度信息化的社会,电力传输与分配系统的稳定运行至关重要。作为连接各个电力设备的纽带,高压线缆的质量直接关系到电力系统的安全性和稳定性。在定制高压线缆行业中&a…

Apache DolphinScheduler用户线上Meetup火热来袭!

Apache DolphinScheduler 社区 8 月用户交流会精彩继续!本次活动邀请到老牌农牧产品实业集团铁骑力士架构工程师,来分享Apache DolphinScheduler在现代农牧食品加工场景中的应用实践。此外,还将有社区活跃贡献者以Apache DolphinScheduler为例…

C语言进阶 13. 文件

C语言进阶 13. 文件 文章目录 C语言进阶 13. 文件13.1. 格式化输入输出13.2. 文件输入输出13.3. 二进制文件13.4. 按位运算13.5. 移位运算13.6. 位运算例子13.7. 位段 13.1. 格式化输入输出 格式化输入输出: printf %[flags][width][.prec][hlL]type scanf %[flags]type %[fl…