繁体   English   中英

在不同步的情况下读写SysV共享内存(使用信号量,C / C ++,Linux)

[英]Reading and writing to SysV shared memory without synchronization (use of semaphores, C/C++, Linux)

我使用SysV共享内存让两个进程相互通信。 我不希望代码变得复杂,所以我想知道是否真的需要使用信号量来同步对共享内存的访问。 在我的C / C ++程序中,父进程从共享内存中读取,子进程写入共享内存中。 我编写了两个测试应用程序,以查看是否会产生诸如分段错误之类的错误,但我无法(Ubuntu 10.04 64bit)。 即使两个进程在while循环中不停地写入同一共享内存也不会产生任何错误。

我希望有人对此事有经验,可以告诉我是否真的必须使用信号量来同步访问,或者我是否可以不进行同步。

谢谢

如果您不使用某种互斥锁,那么您将比其他任何事情更容易遭受与中断有关的怪异和计时错误。

假设您的孩子在被抢占时正在对共享内存进行写操作。 共享内存现在处于“坏”状态-它的一部分与子进程的一种状态相关,其余与该状态之前的状态有关-很有可能您的父级可以在子进程之前重新激活。 然后,您已损坏状态。

也许可以在短期内摆脱这种情况,但稍后发现奇怪的错误。

不管有多少进程尝试“同时”执行写入正确映射的内存地址,都不会产生分段错误。 同步的目的是保持数据一致性。

如果满足以下所有条件,则可以避免信号灯和互斥锁:

  1. 您只有一个线程写入给定地址。

  2. 写入的数据是原子的 -意味着可以在一个I / O操作中进行传输。 字符和整数之类的简单事物在传输时通常是原子的。 许多结构,字符串和数组在复制时不是原子操作,因为它们通常由多个I / O大小的元素组成。

  3. 数据项的有效性不依赖于任何其他数据。

  4. 访问数据时,请使用关键字“ volatile”以避免过时的取消引用。

如果不满足以上任何条件,则如果要保证数据一致且有效,则必须使用某种形式的同步。

如前所述,这是数据完整性问题,而不是段错误。

如果这是一个问题,请使用:管道-这是要实现的简单IPC系统,父级中可能有6行代码,子级中相同

http://tldp.org/LDP/lpg/node11.html

除了所有出色的响应之外,还请看一看boost::interprocess库-对于将类似C ++ STL的容器保存在共享内存中非常方便。 它是通过Unixen上的POSIX共享内存而不是SysV, shmem_open(3)等实现的,您可能也对此感兴趣。

这是一种稍微不同的方法:如果您可以保证读/写器不会意外地抢占彼此,则不需要在它们之间进行同步。

例如,您可以保证在Linux上,如果对访问共享内存的所有进程都使用了调度程序策略SCHED_FIFO (请参阅sched_setscheduler(2) ),并且它们以相同的实时优先级运行并且都被锁定为相同的CPU内核(在多核系统上)。 然后,如果读取器正在执行,它将是唯一执行的进程,直到它选择等待某种条件或等待计时器。 即使写入器从正在等待的某种状态中唤醒,在读取期间,调度程序也不会让写入器运行,直到读取器完成。

我建议使用一个标志来表示访问权限,就像写者线程将创建该标志一样,一旦写完,写者线程可以将其设置为标志++,阅读器线程也将执行该操作。 这样可以避免使用Mutex和锁定开销。 我已经使用过这个并且信任我flag-和flag ++主要是原子的:-)

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM