C信号量:sem_wait抛出莫名其妙的错误

mar*_*olk 1 c semaphore

我正在研究一个我们必须使用信号量来解决的问题.我有一个数组,其中包含两个信号量,gsem并给出一定的条件调用sem_wait(&(gsem[me])),这应该等到特定进程被唤醒.但是,出于某种原因,它给了我错误Bad file descriptor.我向上看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     } 
Run Code Online (Sandbox Code Playgroud)

我应该注意这是一项家庭作业,我们需要使用信号量.教授称之为"男女皆宜的浴室".男人和女人都可以使用它,但不能同时使用它.inside[opp]是浴室里异性的人数.waiting[opp]是等待使用它的异性的数量.screen是一个锁定访问权限的信号量stdout.该解决方案基于我们的教科书中使用传递接力棒的读者/作者问题的解决方案.

我还应该注意,我们首先必须在Ada中编写解决方案,然后将其转换为C.我的Ada解决方案有效,我逐字翻译.我确定这是一些小的语法细节.最后,我正在研究Snow Leopard,如果有帮助的话.

pax*_*blo 6

请记住,Single UNIX Spec可能不一定是您案例中的控制文档.当然,它应该是,但由于您实际上没有指定平台,可能是您在一个决定遵循不同规则和/或有其他返回代码的环境中.

有几件事需要检查.

1 /你确定sem_wait会返回-1吗?我已经看到编码员只是errno在接听电话后检查,没有意识到大多数电话在成功时没有将其设置为零,而是他们只是不管它.如果在呼叫之前errno设置了这种情况,则可能会出现这种情况.EBADF sem_wait

2 /您是否遵循了创建信号量的所有规则,例如初始化它们?

3 /您指的是有效的信号量吗?首先,您确定该me指数不在范围之外吗?

没有看到一些代码,那就是我必须给出的所有建议.


我发现粗略谷歌的一件事sem_wait ebadf在这里.事实证明,这是errno在线程环境中使用而不包含正确标头的问题.

通过这样做,正在使用全局errno 而不是正确的线程(这将给出特定于线程的errno).

这是你的问题,我不知道,但它可能值得研究.


并且更密切地关注这一系列信息,还有其他一些可能性.

4 /您是否正在使用sem_init初始化信号量.如果是,请检查其返回值.这些消息来自2008年所以它可能是过时的信息,但OSX可能仍然不支持sem_init,更喜欢sem_open(见这里).你真的应该检查从返回代码所有sem_功能以及,仅仅是某些(如果你使用sem_init他们所有的(如果它是不支持的),并且只检查一个,你会发现他们失败).

5/在OSX下的线程函数链中存在(是?)竞争条件,errno其中__error函数pthread_self在使用之前调用另一个库调用errno(在主线程中或current_thread->errno在其他线程中).从技术上讲,这是不允许的,并且有一个小窗口可能会出现问题.

  • 哇你是对的,不支持`sem_init`.甚至不是手册页.天哪,Apple.谢谢,paxdiablo. (2认同)