linux - 为什么线程之间是IPC-Mechanism?

标签 linux multithreading

关闭。这个问题需要更多focused .它目前不接受答案。












想改善这个问题吗?更新问题,使其仅关注一个问题 editing this post .

8年前关闭。




Improve this question




我有一个疑问,线程共享除堆栈之外的所有进程段。因此,为了在线程之间进行通信,假设我想将一个单词“Hello”从一个线程传递到另一个线程,IPC 机制(例如消息队列)需要什么。

最佳答案

在一个进程中的线程之间以及与其他进程中的线程之间有各种各样的数据通信方式。您只需选择一款适合您的需求即可。

共享内存

单个进程中的线程可以访问进程中的所有内存,尽管正如您所说,它们有自己的堆栈。这意味着一个线程与另一个线程共享一块内存是相当直接的。通常你会使用某种信号量来确保它们不会同时尝试访问内存(这通常会导致非常困惑的程序行为......)。

代码快速且高效,因为数据永远不会被复制,但要正确执行复杂的程序可能非常困难。

消息队列、管道等

然而,消息队列之类的东西是一种将数据从一个线程使用的内存发送到另一个线程使用的内存的方式。

有很多优点,因为使用内存队列编写复杂程序通常比共享内存容易得多。但是,内存队列本质上效率较低。这是因为操作系统中的消息队列实现必须复制数据(通常是两次)。

线程与进程

对于共享内存方法,将所有线程放在一个进程中是很自然的,而对于消息队列,将线程放在单独的进程中开始变得更加自然。不过也无所谓。大多数操作系统允许进程将它们的一些内存暴露给其他进程(Linux 上的/dev/shm),并且任何进程都可以获取命名信号量。

因此,从架构上讲,“一个进程中的所有线程”与“它们自己进程中的所有线程”的问题并不重要。您可能需要牢记操作系统的线程与进程上下文切换时间,因为这也会影响效率。

可扩展性

如果您选择像管道这样的 IPC 机制,那么就有了可扩展性的机会。特别是管道的行为与套接字非常相似。因此,如果您的程序在您的计算机上运行速度太慢,那么将管道转换为套接字并将线程放置在分布在两台或多台计算机上的进程中并没有那么多工作。所以使用管道意味着将你的应用程序变成多机分布式应用程序并不困难。

当然,套接字要慢得多,因此在确定之前,您必须考虑每秒实际需要从一个线程发送到另一个线程的数据量。

CPU 内存架构

还记得我说过内存队列比共享内存效率低吗?嗯,现在这不是很清楚。 Intel 当前的架构,尤其是 AMD 的架构,意味着复制数据与仅仅读取数据并没有太大区别。

看看英特尔芯片之间的 QPI 链接,想想在电子层面上实际发生了什么。假设您的机器中有两个已填充的 CPU 插槽,并且您的应用程序有两个线程共享一个内存缓冲区。

为了让一个芯片上的线程访问驻留在另一个芯片内存中的数据,它必须通过 QPI 链接读取该数据。

现在,假设这些线程使用消息队列。操作系统必须将数据从一个线程复制到另一个线程。这意味着通过 QPI 链接读取数据。这与 QPI 链接上的事件量大致相似。

AMD 的架构让它变得更加明目张胆;它们与 QPI 的等价(和优越性...)称为 Hypertransport,它在 AMD 的芯片内部运行。

事情并没有那么简单。缓存使事情变得更加复杂。但是对于某些程序的大量线程分布在共享大量数据的两个或多个芯片上,QPI 有可能使一切变慢。英特尔当然知道这一点并对其进行设计,以便通常 QPI 不会成为瓶颈。但是,如果您的程序不是英特尔在选择 QPI 参数时所考虑的,那么性能可能会低于预期。

实际上,在某些情况下可以非常小心地使用管道、消息队列等,并最终获得比使用共享内存的程序更好的性能。

但是,出于简单性和可靠性的原因,我仍然会选择管道和消息队列。

关于linux - 为什么线程之间是IPC-Mechanism?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/18798119/

相关文章:

c - 在 x86_64 linux 中重定位超过 2GB 的程序时出现链接器错误?

linux - chroot 如何影响动态库内存使用?

linux - 在 Linux 中使用 --enable-libxcb 构建 FFMPEG

linux - Qt 4.8.5 -- 编译 ResourceFile.qrc 时出错

ruby - sleep 0 有特殊意义?

java - 图表上的 setFont 问题 (JFreeChart)

java - CyclicBarrier 启动执行不同逻辑的并行线程

android - 在 Android 中使用本地存储使用 Parse 查询效率

c# - ASP.NET Core线程中默认的IServiceProvider安全吗?

java - 如何让线程等待另一个类的方法完成