C信号量:sem_wait抛出莫名其妙的错误
我正在研究一个我们必须使用信号量来解决的问题。 我有一个包含两个信号量的数组, sem_wait(&(gsem[me]))
,并且在某些条件下调用sem_wait(&(gsem[me]))
,它应该等到特定进程被唤醒。 但是,由于某种原因,它给了我错误的Bad file descriptor
。 我sem_wait
了一下sem_wait
,Open Group规范说这不是sem_wait
可能导致的错误。 这让我的整个程序变得疯狂,我不知道为什么会失败。
编辑:违规代码,根据要求。
120 sem_wait(&mutex); 121 if (inside[opp] > 0 || waiting[opp] > 0) { 122 sem_wait(&screen); 123 printf("%s %u waiting\n", names[me], t); 124 sem_post(&screen); 125 waiting[me]++; 126 sem_post(&mutex); 127 int hg = sem_wait(&(gsem[me])); 128 if (hg < 0) 129 printf("%s\n", strerror(errno)); 130 }
我应该注意这是一项家庭作业,我们需要使用信号量。 教授称之为“男女皆宜的卫生间”。 男人和女人都可以使用它,但不能同时使用它。 inside[opp]
是卫生间异性的人数。 waiting[opp]
是等待使用它的异性的数量。 screen
是一个信号量,它锁定对stdout
访问。 该解决方案基于我们的教科书中使用传递接力棒的读者/作者问题的解决方案。
我还应该注意,我们首先必须在Ada中编写解决方案,然后将其转换为C.我的Ada解决方案有效,我逐字翻译。 我确信这是一些小的语法细节。 最后,我正在研究Snow Leopard,如果有帮助的话。
请记住,Single UNIX Spec可能不一定是您案例中的控制文档。 当然,它应该是,但由于您实际上没有指定平台,可能是您在一个决定遵循不同规则和/或有其他返回代码的环境中。
有几件事需要检查。
1 /你确定 sem_wait
返回-1吗? 我见过编码员只是在通话后检查errno
,没有意识到大多数通话都没有在成功时将其设置为零,而是他们只是不管它。 如果在sem_wait
调用之前将errno
设置为EBADF
,则可能会出现这种情况。
2 /您是否遵循了创建信号量的所有规则,例如初始化它们?
3 /您指的是有效的信号量吗? 首先,你确定me
指数不超出范围吗?
没有看到一些代码,那就是我必须给出的所有建议。
我发现sem_wait ebadf
粗略谷歌的sem_wait ebadf
就在这里 。 事实certificate,这是在线程环境中使用errno
而不包含正确标头的问题。
通过这样做,正在使用全局errno
值而不是正确的线程宏 (这将给出特定于线程的errno
)。
这是你的问题,我不知道,但它可能值得研究。
并且更密切地关注这一系列信息,还有其他一些可能性。
4 /您是否使用sem_init
初始化信号量。 如果是,请检查其返回值。 消息来自2008年,所以它可能是过时的信息,但OSX可能仍然不支持sem_init
,更喜欢sem_open
(见这里 )。 你真的应该检查你所有 sem_
函数的返回码,只是为了确定(如果你对它们全部使用sem_init
(如果它不受支持)并且只检查一个,你可能会发现它们都失败了)。
5 / OSX下的线程errno
函数链中存在(是?) 竞争条件 ,其中__error
函数在使用errno
之前调用另一个库调用pthread_self
(在主线程中,或者在其他线程中使用current_thread->errno
)。 从技术上讲,这是不允许的,并且有一个小窗口可能会出现问题。