简体   繁体   English

C信号灯:sem_wait引发莫名其妙的错误

[英]C semaphores: sem_wait throwing inexplicable error

I'm working on a problem which we have to use semaphores to solve. 我正在研究一个必须使用信号量来解决的问题。 I have an array which contains two semaphores, gsem , and given certain conditions call sem_wait(&(gsem[me])) , which is supposed to waiting until that particular process is woken up. 我有包含两个信号量,阵列gsem ,和给定的特定条件下调用sem_wait(&(gsem[me]))这是为了等待,直到该特定的过程被唤醒。 However, for some reason it gives me the error Bad file descriptor . 但是,由于某种原因,它给我错误的错误Bad file descriptor I looked up sem_wait and the Open Group spec says this is not an error sem_wait can cause. 我查找了sem_wait ,Open Group规范说这不是sem_wait可能导致的错误。 This is making my whole program crazy and I have no idea why this is failing. 这使我的整个程序变得疯狂,我不知道为什么会失败。

EDIT: Offending code, as requested. 编辑:违反要求的代码。

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     } 

I should note this is a homework assignment for which we are required to use semaphores. 我应该注意,这是一项作业,我们需要使用信号量。 The professor calls it the "unisex bathroom". 教授称其为“男女皆宜的浴室”。 Either men and women can use it, but not simultaneously. 男人和女人都可以使用它,但不能同时使用。 inside[opp] is the number of people of the opposite sex in the bathroom. inside[opp]是洗手间中异性的人数。 waiting[opp] is the number of the opposite sex waiting to use it. waiting[opp]是等待使用它的异性的数量。 screen is a semaphore which locks access to stdout . screen是一个信号灯,用于锁定对stdout访问。 The solution is based on a solution to the readers/writers problem given in our textbook which uses passing the baton. 该解决方案基于对我们的教科书中使用传递指挥棒的读者/作家问题的解决方案。

I should also note that we first had to code a solution in Ada and then convert it to C. My Ada solution works, and I translated it verbatim. 我还应该注意,我们首先必须在Ada中编写一个解决方案,然后将其转换为C。我的Ada解决方案有效,并且我逐字翻译了它。 I'm sure it's some minor syntactical detail. 我确定这只是一些语法上的细节。 Lastly, I'm working on Snow Leopard, if that helps. 最后,如果有帮助,我正在研究Snow Leopard。

Keep in mind that the Single UNIX Spec may not necessarily be the controlling document in your case. 请记住,根据您的情况,Single UNIX Spec不一定是控制文档。 Granted, it probably should be, but since you haven't actually specified the platform, it may be that you're in an environment that decided to follow different rules and/or have other return codes. 当然,可能应该如此,但是由于您实际上尚未指定平台,因此可能是您所处的环境决定遵循不同的规则和/或具有其他返回码。

A couple of things to check. 需要检查的几件事。

1/ Are you sure that sem_wait is returning -1? 1 /您确定 sem_wait返回-1吗? I've seen coders simply check errno following a call, not realising that most calls don't set it to zero on success, rather they simply leave it alone. 我已经看到编码人员只是在通话后检查errno ,却没有意识到大多数通话不会在成功后将其设置为零,而是只是将其搁置一旁。 It's possible that such a situation would arise if errno were set to EBADF before the sem_wait call. 如果在sem_wait调用之前errno设置为EBADF 则可能会出现这种情况。

2/ Have you followed all the rules in creating the semaphores, such as initialising them? 2 /您是否在创建信号量时遵循了所有规则,例如对其进行初始化?

3/ Are you referring to a valid semaphore? 3 /您是指有效的信号量吗? Primarily, are you certain that the me index is not out of range? 首先,您确定me索引没有超出范围吗?

Short of seeing some code, that's about all the advice I have to give. 缺少一些代码,这就是我必须提供的所有建议。


One thing I found with a cursory google of sem_wait ebadf is here . 有一两件事,我发现有一个粗略的谷歌sem_wait ebadf在这里 Turns out this was a problem with using errno in a threaded environment without including the correct headers. 原来这是在线程环境中使用errno而不包含正确的标头的问题。

By doing that, the global errno value was being used rather than the correct threaded macro (which would give the thread-specific errno ). 这样,将使用全局errno ,而不是使用正确的线程 (后者将提供特定于线程的errno )。

Whether that's your problem, I have no idea, but it may be worth looking into. 不管是您的问题,我不知道,但是可能值得研究。


And following that chain of messages a little more closely, there are some other possibilities. 沿着这条消息链走得更近一些,还有其他可能性。

4/ Are you using sem_init to initialise the semaphores. 4 /您是否正在使用sem_init初始化信号量。 If so, check its return value. 如果是这样,请检查其返回值。 The messages are from 2008 so it may be dated information, but OSX may still not support sem_init , preferring sem_open (see here ). 该消息来自2008年,因此可能是过时的信息,但是OSX可能仍不支持sem_init ,而更喜欢sem_open (请参见此处 )。 You really should check the return codes from all your sem_ functions as well, just to be certain (if you're using sem_init for them all (and if it's unsupported) and are only checking one, you may find that they're all failing). 您确实应该检查所有 sem_函数的返回码,以便确定(如果您对所有函数都使用sem_init (并且不支持),并且仅检查其中一个,则可能会发现它们失败了)。

5/ There is (was?) a race condition in the thread errno function chain under OSX where the __error function called another library call pthread_self before using errno (in main thread, or current_thread->errno in other threads). 5 /在OSX ,线程errno函数链中存在(曾经是) 竞争状态 ,在调用errno (在主线程中,在其他线程中使用current_thread->errno )之前,调用另一个库的__error函数调用pthread_self Technically this is not allowed and there was a small window where problems could occur. 从技术上讲,这是不允许的,并且有一个很小的窗口,可能会发生问题。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM