如何检查c中信号量的状态?
Posted
技术标签:
【中文标题】如何检查c中信号量的状态?【英文标题】:How can I check the state of a semaphore in c? 【发布时间】:2012-07-19 11:16:17 【问题描述】:我有一个全局静态变量,它是一个信号量,因为我正在编写一个库而不是一个程序。
在使用该库的main()
程序中,有fork()
的调用,以及基于共享内存的对管道的读取和写入。
例如,这是使用我的库的main()
:
#include <stdio.h>
#include <stdlib.h>
#include "my_pipe_shared_memory_based.h"
int main()
int spd, pid, rb;
char buff[4096];
my_new_init();
if (my_new_fifo("tmp_shm_pipe",0666) < 0)
perror("my_new_fifo");
exit(1);
if (fork())
spd = my_new_open("tmp_shm_pipe", O_RDONLY, 0600);
if (spd < 0)
perror("PARENT: my_new_open");
exit(1);
rb = my_new_read(spd, buff, sizeof(buff));
if (rb > 0)
write(1, buff, rb);
else
spd = my_new_open("tmp_shm_pipe", O_WRONLY, 0600);
if (spd < 0)
perror("SON: my_new_open");
exit(1);
my_new_write(spd, "hello world!\n", sizeof("hello world!\n"));
my_new_close(spd);
my_new_un_link("tmp_shm_pipe");
my_new_finish();
return 0;
现在,我想在每次进程在方法中读取和/或写入之前使用信号量:
my_new_write()
my_new_read()
现在,问题是,我怎样才能在上面请求的方法中每次检查信号量的状态(例如my_new_write
&my_new_read
),所以我可以让进程做他的事情,或者阻止它,如果另一个进程当前正在读/写?
谢谢
【问题讨论】:
您的信号量“mySemaphore”在不同进程中不可见。看我的回答。 您也可以简单地尝试在 sem_open 调用中将“S_IRUSR | S_IWUSR”替换为“S_IRWXO”。它应该可以工作,虽然我不确定:) @JoãoFernandes:试过了,但输出仍然只是:Output:
而不是 :Output:hello world!
。也许还有其他想法?谢谢
您是否验证过您的信号量正在正确初始化,并且--once--,而不是每个进程一次?您的每个信号量操作的返回码是什么?
@SanJacinto:是的,我加倍检查了。它从零 (0) 开始,到 1,然后回到零。从不大于 1 或小于 0。
【参考方案1】:
这里的关键是您必须确保确保互斥的信号量对两个进程都是可见的。为此,您需要分配共享内存并在分叉之前初始化信号量。例如,对于这个任务,您可以使用 mmap。示例(没有任何错误检查):
sem_t *sem = mmap(NULL, sizeof(sem_t),
PROT_READ | PROT_WRITE, MAP_ANONYMOUS | MAP_SHARED, 0, 0);
之后,使用 sem_init 初始化信号量并确保第二个参数 pshared 不为零。手册说:
如果 pshared 不为零,则信号量在进程之间共享,并且应该位于共享内存区域中(请参阅 shm_open(3)、mmap(2) 和 shmget(2))。 (由于 fork(2) 创建的子进程继承了其父进程的内存映射,它也可以访问信号量。)任何可以访问共享内存区域的进程都可以使用 sem_post(3)、sem_wait(3) 等对信号量进行操作.
最后fork进程,正常使用sem_wait和sem_post。
编辑:
真的,尝试替换这个:
mySemaphore = sem_open("mySemaphore", O_CREAT, S_IRUSR | S_IWUSR);
有了这个:
mySemaphore = mmap(NULL, sizeof(sem_t),
PROT_READ | PROT_WRITE, MAP_ANONYMOUS | MAP_SHARED, 0, 0);
sem_init(mySemaphore, 1, 1);
在 my_new_open 函数中
【讨论】:
您似乎正确地创建了共享内存区域,但绝对不是信号量。 那行sem_init(mySemaphore, 1, 1);
导致死锁,程序没有停止运行。奇怪..我什至无法调试代码,因为我在 main()
中是 forking
。我检查了sem_init
的man
和最后一个1
(最右边的操作数)应该确实是1 表示互斥,但仍然处于僵局。
@ron,仔细查看您的代码,您似乎还有其他问题。例如,读取似乎是非阻塞的,这可能是问题的根源,因为您可能希望等到管道中有可用数据。【参考方案2】:
sem_trywait() 和 sem_wait() 不是您要找的东西吗?用信号量句柄调用它们,你就会知道它们的状态。
http://pubs.opengroup.org/onlinepubs/7908799/xsh/sem_trywait.html
不确定信号量,但带有互斥锁的 pthread_cond_timedwait() 还可以让您检查同步状态而不会阻塞线程(或给出超时)。
【讨论】:
Victor,我已经尝试过了(我的意思是线程)。现在我尝试使用sem_wait
和 sem_post
但代码仍然不同步。有什么想法吗?我应该发布代码吗?谢谢
肯定的,把读/写函数贴出来,我们看看。
完成了,我发布了 3 个方法:open
、read
和 write
。谢谢。以上是关于如何检查c中信号量的状态?的主要内容,如果未能解决你的问题,请参考以下文章