我有一个程序,该程序创建一些共享内存以共享一些数据和一些信号,在其中写入一些数据,然后其他进程连接到它并读取该数据并执行一些操作,并使用第一个进程创建的未命名信号在它们之间进行同步。
完成所有操作后,是否只有在完成所有其他处理后才能销毁信号量(使用sem_destroy())?还是让我第一个进程等待其他进程完成其工作然后销毁信号量会更好吗?这样,我想我应该实现任何沟通渠道,但不确定如何做到这一点。
编辑:提供一些代码
这是我的编写过程,它创建了简化的共享内存(省略了错误处理):
int fd_shm = shm_open(SHM_NAME, O_RDWR | O_CREAT | O_EXCL,S_IRUSR | S_IWUSR);
/* Resize the memory segment */
ftruncate(fd_shm, sizeof(ShmExampleStruct))
/* Map the memory segment */
ShmExampleStruct *example_struct = mmap(NULL, sizeof(*example_struct), PROT_READ | PROT_WRITE, MAP_SHARED,fd_shm, 0);
close(fd_shm);
sem_init(&(example_struct->sem), 1, 1)
在ShmExampleStruct内部,我得到了数据和信号量。这段代码之后,它将一些数据写入example_struct
阅读过程的代码可能是这样的:
/* We open the shared memory */
int fd_shm = shm_open(SHM_NAME, O_RDONLY, 0);
/* Map the memory segment */
ShmExampleStruct *example_struct = mmap(NULL, sizeof(*example_struct), PROT_READ, MAP_SHARED, fd_shm, 0);
close(fd_shm);
然后从example_struct做一些阅读
如果我先启动书写过程,然后启动某些阅读过程,那么销毁信号量的最佳方法是什么?从理论上讲,写作过程应该在阅读之前开始和结束。
正如Michael Kerrish(第1103页)的LPI中所述,“未命名的信号量应在其底层内存被释放之前被销毁”。
此外,在书中指出,“如果信号量位于POSIX共享内存区域中”,这就是您的情况(example_struct->sem
),“那么,只有在所有进程均不使用信号量之后且在共享内存之前,才应销毁信号量。对象未与shm_unlink()
“链接。
因此,只有在没有进程/线程正在等待的情况下销毁未命名的信号量才是安全的。它导致不确定的行为:(1)如果在其他进程/线程被阻塞时信号被销毁了;(2)是否使用了被破坏的信号量。
为了确保这种情况,您需要使用shm_unlink()
函数删除共享内存对象,并且只能在之后调用sem_destroy()
。为此,您需要同步进程以安全地破坏信号量。
例如,如果要fork()
在父进程中使用创建进程(读取器和写入器),则可以在所有子进程完成后销毁父进程中的共享内存和信号灯。为了同步,您可以使用该wait()
功能。
本文收集自互联网,转载请注明来源。
如有侵权,请联系[email protected] 删除。
我来说两句