我有两个进程A和B.它们之间的通信是通过共享内存。
A ---> write->sharedmemory-----> Read-->B.
B如何知道A已经在共享内存中写了一些内容。
答案 0 :(得分:2)
写入共享内存,然后A向B发送信号,B捕获信号并从内存中读取
B通常不知道,A需要告诉它。
可以使用带有轮询的管道,带有挂钩或A的系统信号可以在内存准备就绪时按需执行B(以及更多选项)
答案 1 :(得分:0)
您不知道shared memory何时发生了变化,因为根据定义,共享内存不涉及任何同步机制。
同步是(如共享内存)特定的操作系统。
在Linux上,shm_overview(7)概述了Posix共享内存设施,并正确地引用了sem_overview(7),其中讨论了作为同步机制的Posix信号量。您还可以查看Posix消息队列,请参阅mq_overview(7)。
您还可以使用pipe(7) - s(可能还使用多路复用系统调用,如poll(2) ...),socket(7) - s(可能是unix(7)套接字,如果全部流程在同一个系统上),特定于Linux的eventfd(2),signal(7) - s - 但我不建议在这种情况下使用它们等等。
您可能需要atomic operations。 C11提供<stdatomic.h>
(而C ++ 11有<atomic>
)。 GCC提供atomic builtins。
您还可以考虑使用pthreads(然后包含<pthread.h>
)。您将对互斥锁(请参阅pthread_mutex_lock等等...)和条件变量感兴趣(请参阅pthread_cond_wait等等...)。
另请阅读Advanced Linux Programming以概述Linux上的各种IPC机制。
答案 2 :(得分:0)
这实际上取决于你正在使用的操作系统。
您可以使用信号通知进程B您已在共享内存中写入内容。
见signal.h
其他方式是使用互斥锁,管道,插座......
答案 3 :(得分:0)
有很多组织同步的方法,但它们都是系统特定的。
您可以分配共享内存的一个字节来传递信息。它最初是0.当A将所有信息写入共享存储器的其余部分时,它可以将1写入同步字节。然后等待,最好不是忙等待,同步字节变回0.同时,B正在等待,最好不是忙等待,同步字节变为1.当它发生时,它将复制消息超出共享内存,然后将同步字节设置回0,然后返回其循环,等待同步字节再次更改为1。
当然,在两个过程场景中,A和B可以简单地在同步字节的检查之间以nanosleep()
或类似的短延迟循环;这比检查同步字节的无约束循环要好。
“不是忙碌的等待”部分意味着您通常最终需要两个信号量或类似的东西,以便您可以等待而不必在执行此操作时使CPU饱和,然后在数据可用时立即唤醒。当有消息出现时,作者会设置一个信号量;消息被消费后,另一个由读者设置。信号量的一个优点是你可以拥有多个读者或多个作家。
您也可以使用一对管道,一个用于A写入B,另一个用于B写入A. A会将消息复制到共享内存中,并在有消息时将一个字节写入管道B共享内存,然后从B管道读取一个字节。同时,B将从A管道读取一个字节,将消息从共享内存中复制出来,并在管道上写一个字节到A,表明它已完成共享内存中的消息。 (但是你可能会问自己 - 为什么不使用管道而不是共享内存。)