Тупик при закрытии канала, когда другой поток читает этот канал? - PullRequest
1 голос
/ 20 января 2012

У меня тупик при закрытии трубы:

close(myPipeFD);

Другой поток, поток чтения, находится в состоянии чтения блокировки из этого точно такого же канала:

ssize_t sizeRead = read(myPipeFD, buffer, bufferSize);

Может ли это быть причиной такого тупика? Я думал, что read немедленно вернул бы sizeRead == 0? Должен ли я испустить прерывание в этой теме чтения?

1 Ответ

0 голосов
/ 03 февраля 2014

Не безопасно закрывать файловый дескриптор, когда его может использовать другой поток, по нескольким причинам.

Как вы обнаружили, некоторые системные вызовы, которые могут блокировать ожидание файлового дескриптора, могут вести себя непредсказуемым образом, если этот файловый дескриптор закрыт.

Но есть и другие проблемы. Предположим, что первый поток закрывает файловый дескриптор как раз перед тем, как второй поток вводит в него вызов read(). Предположим также, что третий поток одновременно открывает файл или сокет. Новый дескриптор файла получит тот же номер, что и тот, который был только что закрыт. Второй поток будет читать из неправильного файлового дескриптора!

В общем, вам нужно убедиться, что только один поток работает с дескриптором файла одновременно. Потоки должны «владеть» файловыми дескрипторами. Вы можете передавать права собственности от одного потока другому, но каждый должен владеть только одним.

Если вам нужно отменить операции, вам нужно использовать неблокирующий ввод-вывод и такие вещи, как select(), когда вам нужно заблокировать ожидание данных. Кроме того, вам необходимо включить межпотоковый канал связи (например, канал) в вызов select(), который будет механизмом, посредством которого один поток отправляет запрос другому, чтобы закрыть один из своих файловых дескрипторов.

Вам также следует обратить внимание на диспетчеризацию ввода-вывода или асинхронные механизмы, такие как управляемый цикл выполнения NSFileHandle.

...