Семафоры C: sem_wait бросает необъяснимую ошибку - PullRequest
1 голос
/ 02 мая 2010

Я работаю над проблемой, для решения которой нам нужно использовать семафоры. У меня есть массив, который содержит два семафора, 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     } 

Я должен отметить, что это домашнее задание, для которого мы обязаны использовать семафоры. Профессор называет это «ванной унисекс». Его могут использовать как мужчины, так и женщины, но не одновременно. inside[opp] - количество людей противоположного пола в ванной комнате. waiting[opp] - номер противоположного пола, ожидающего его использования. screen - это семафор, который блокирует доступ к stdout. Решение основано на решении проблемы читателей / писателей, приведенной в нашем учебнике, в которой используется передача эстафеты.

Я должен также отметить, что сначала мы должны были кодировать решение в Ada, а затем преобразовать его в C. Моё решение Ada работает, и я перевел его дословно. Я уверен, что это небольшая синтаксическая деталь. Наконец, я работаю над Snow Leopard, если это поможет.

1 Ответ

6 голосов
/ 02 мая 2010

Имейте в виду, что отдельная спецификация UNIX не обязательно может быть управляющим документом в вашем случае.Конечно, возможно, так и должно быть, но поскольку вы фактически не указали платформу, возможно, вы находитесь в среде, которая решила следовать другим правилам и / или иметь другие коды возврата.

Паравещей для проверки.

1 / Вы уверены , что sem_wait возвращает -1?Я видел, как кодеры просто проверяют errno после вызова, не понимая, что большинство вызовов не устанавливают его на ноль в случае успеха, а просто оставляют его в покое.Вполне возможно, что такая ситуация возникнет, если errno будет установлен на EBADF до вызова sem_wait.

2 / Вы следовали всем правилам при создании семафоров,например, их инициализация?

3 / Вы имеете в виду действительный семафор?Прежде всего, вы уверены, что индекс me не выходит за пределы допустимого?

Если не считать какой-либо код, это все советы, которые я должен дать.


Одна вещьЯ нашел с беглым Google из sem_wait ebadf здесь здесь .Оказывается, это была проблема с использованием errno в многопоточной среде без включения правильных заголовков.

При этом использовалось глобальное errno значение , а не правильное макрос (который дал бы специфичный для потока errno).

Если это ваша проблема, я понятия не имею, но, возможно, стоит разобраться.


И, следуя этой цепочке сообщений чуть более внимательно, есть и другие возможности.

4 / Используете ли вы sem_init для инициализации семафоров.Если это так, проверьте его возвращаемое значение.Сообщения отправлены с 2008 года, поэтому они могут быть устаревшей информацией, но OSX может все еще не поддерживать sem_init, предпочитая sem_open (см. здесь ).Вы действительно должны проверить коды возврата из всех ваших sem_ функций, просто чтобы быть уверенным (если вы используете sem_init для них всех (и если он не поддерживается) и проверяете только одну, вы можете обнаружить, что они all не работают).

5 / Существует (было?) условие race в цепочке функций потока errno подOSX, где функция __error вызывает другой вызов библиотеки pthread_self перед использованием errno (в основном потоке или current_thread->errno в других потоках).Технически это недопустимо, и было небольшое окно, где могли возникнуть проблемы.

...