Мини-сага
Вы не упоминаете среду, в которой вы запускаете оригинальный код.Я изменил ваш код для использования nanosleep()
(поскольку, как я уже упоминал в комментарии к вопросу, sleep()
принимает целое число и, следовательно, sleep(0.2)
эквивалентно sleep(0)
), и скомпилировалпрограмма на MacOS X 10.6.4.
Без проверки ошибок
Работает нормально;потребовалось около 100 секунд для запуска с коэффициентом вероятности 0,5 (как и следовало ожидать; я изменил его до 0,05, чтобы сократить время выполнения примерно до 10 секунд), и сгенерировал случайную строку - в некоторых случаях.
Иногда я ничего не получал, иногда я получал больше, а иногда я получал меньше данных.Но я не увидел дамп ядра (даже с 'ulimit -c unlimited', чтобы разрешить произвольно большие дампы ядра).
В конце концов, я применил некоторые инструменты и увидел, что всегда получаю 1025 символов (1024 сгенерировано плюс перевод строки), но довольно часто я получаю 1024 символов ASCII NUL.Иногда они появляются посередине, иногда в начале и т. Д .:
$ ./pth | tpipe -s "vis | ww -w64" "wc -c"
1025
\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000
\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000
\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000
\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000
\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000
\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000
\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000
\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000
\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000
\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000
\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000
\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000
\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000
\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000
\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000
\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000
\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000
\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000
\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000
\000\000\000\000\000\000\000\000ocriexffwgdvdvyfitjtvlzcoffhusjo
zyacniffpsfswesgrkuxycsubufamxxzkrkqnwvsxcbmktodessyohixsmuhdovt
hhertqjjinzoptcuqzertybicrzaeyqlyublbfgutcdvftwkuvxhouiuduoqrftw
xjkgqutpryelzuaerpsbotwyskaflwofseibfqntecyseufqxvzikcyeeikjzsye
qxhjwrjmunntjwhohqovpwcktolcwrvmfvdfsmkvkrptjvslivbfjqpwgvroafzn
fkjumqxjbarelbrdijfrjbtiwnajeqgnobjbksulvcobjkzwwifpvpmpwyzpwiyi
cdpwalenxmocmtdluzouqemmjdktjtvfqwbityzmronwvulfizpizkiuzapftxay
obwsfajcicvcrrjehjeyzsngrwusbejiovaaatyzouktetcerqxjsdpswixjpege
blxscdebfsptxwvwsllvydipovzmnrvoiopmqotydqaujwdykidmwzitdsropguv
vudyfiaaaqueyllnwudfpplcfbsngqqeyucdawqxqzczuwsnaquofreilzvdwbjq
ksrouwltvaktpdrvjnqahpdqdshmmvntspglexggshqbjrvxceaqlfnukedxzlms
cnapdtgtcoyhnglojbjnplowericrzbfulvrobfn
$
(Программа tpipe похожа на 'tee', но она записывает в каналы вместо файлов (и в стандартный вывод, есливы указываете опцию '-s'); 'vis' взято из 'Среды программирования UNIX' Kernighan & Pike; 'ww' является 'упаковщиком слов', но здесь нет слов, так что это грубая сила переноса по ширине64.)
Поведение, которое я видел, было весьма неопределенным - я получал разные результаты при каждом запуске.Я даже заменил случайные символы на алфавит в последовательности ('a' + i% 26), и все еще получал странное поведение.
Я добавил некоторый код отладочной печати (и счетчик к контексту), ибыло ясно, что семафор context->full
не работал должным образом для читателя - ему разрешалось входить во взаимное исключение до того, как писатель что-либо написал.
С проверкой ошибок
КогдаЯ добавил проверку ошибок к операциям мьютекса и семафора и обнаружил, что:
sem_init(&context.full) failed (-1)
errno = 78 (Function not implemented)
Итак, странные результаты заключаются в том, что MacOS X не реализует sem_init()
.Это странно;сбой функции sem_wait()
с errno = 9 (EBADF 'Bad file descriptor');Сначала я добавил туда чеки.Затем я проверил инициализацию ...
Использование sem_open () вместо sem_init ()
Вызовы sem_open()
успешно выполняются, что выглядит хорошо (имена "/full.sem"
и "/empty.sem"
, флагиO_CREAT, значения режима 0444, 0600, 0700 в разное время и начальные значения 0 и BUFFER_SIZE, как в sem_init()
).К сожалению, первая операция sem_wait()
или sem_post()
завершается неудачно с errno = 9 (EBADF 'Bad file descriptor') снова.
Морали
- Важно проверить условия ошибок при системных вызовах.
- Вывод, который я вижу, является недетерминированным, потому что семафоры не работают.
- Это не меняет «он не падает без поведения
pthread_join()
звонков». - MacOS X не имеет работающей реализации семафора POSIX.