是否可以为进程间通信提供共享全局变量?

Posted

技术标签:

【中文标题】是否可以为进程间通信提供共享全局变量?【英文标题】:Is it possible to have a shared global variable for inter-process communication? 【发布时间】:2020-05-28 07:10:16 【问题描述】:

我需要为我的操作系统类解决并发分配问题。我不想要这里的解决方案,但我缺少一个部分。

我们应该编写一个写入文件、读取文件然后删除文件的进程。这个过程我们应该在两个不同的 shell 中运行两次。为简单起见,这里没有分叉。进程 A 应该写入,进程 B 然后读取,然后进程应该删除文件。之后他们互换角色。

我知道您可以通过锁定轻松实现原子性。使用 while 循环围绕读取和写入部分等,您还可以获得进一步的控制。但是当我运行进程 A 然后进程 B 时,进程 B 将在写入部分之前旋转,直到它获得锁定并且在进程 A 释放锁定时不会进入读取。所以我最好的猜测是有一个读写锁。这些信息必须在进程之间以某种方式共享。我能想到的唯一方法是一些全局变量,但由于两个进程都持有变量的副本,我认为这是不可能的。另一种方法是拥有一个读锁定文件和一个写锁定文件,但这对我来说似乎过于复杂。

有没有更好的办法?

【问题讨论】:

使用共享内存。 进程间通信有多种方式。一些搜索词是:共享内存、管道和套接字。 我认为我们需要使用共享内存。那么当我启动两个进程时,指针会指向同一个内存部分吗? 不,您必须向操作系统请求一些共享内存。您还必须确保两个任务不会同时访问内存(例如使用某种形式的锁定)。使用信号量会更有意义。 好吧,我们不允许使用信号量。我们只需要通过文件锁来实现这一点 【参考方案1】:

您可以使用信号量来确保写入器和删除器等待前一个进程完成其工作。 (详情请使用man sem_init

当使用信号量运行多个进程时,应使用共享内存创建它(man shm_open 了解更多详细信息)。

在此过程中,您将需要与管道数量一样多的信号量。

【讨论】:

我们不允许使用信号量【参考方案2】:

您可以将文件用作锁。两个进程尝试使用 O_EXCL 标志创建具有先前商定名称的文件。只有一个人会成功。成功者获得对资源的访问权。所以在这种情况下,进程 A 应该尝试创建一个名为 foo 的文件,带有 O_EXCL 标志,如果成功,它应该继续写入文件信息。工作完成后,进程 A 应该取消链接 foo。进程 B 应尝试使用 O_EXCL 标志创建文件 foo,如果成功,则尝试读取进程 A 创建的文件。尝试结束后,进程 B 应取消链接文件 foo。这样,任何时候只有一个进程会访问该文件。

【讨论】:

【参考方案3】:

您的问题(文件和文件创建/删除中的交替角色)似乎是在打开/创建文件时使用O_EXCL 标志的候选者。此标志使open(2) 系统调用在文件不存在时成功创建文件,因此它使文件本身显示为信号量。每个进程都可以释放锁(A 或 B),但释放锁的进程只是释放锁并使 拥有 的角色再次可访问。

您会看到两个进程都尝试使用其中一个角色,但如果它们都尝试使用 owner 角色,其中一个会成功,另一个会失败。

只需在 拥有 进程上启用SIGINT 信号处理程序,以允许它在收到信号时删除文件,否则您将离开文件,之后任何进程都无法承担拥有角色(至少您需要手动删除它)。

这是 unix 中第一种锁定功能,早在信号量、共享内存或其他阻塞进程的方法出现之前。它基于系统调用的原子性(不能同时对同一个文件执行两个系统调用)

【讨论】:

以上是关于是否可以为进程间通信提供共享全局变量?的主要内容,如果未能解决你的问题,请参考以下文章

进程间通信IPC之--共享内存

线程间通信的定义及全局变量的方法

进程间通信方式

线程进程间通信机制

进程与线程的区别

线程间的通信同步方式与进程间通信方式