Многопоточное чтение из одной трубы - PullRequest
0 голосов
/ 23 декабря 2011

Я внедряю систему, которая запускает игровые серверы. У меня есть процесс («игровой контроллер»), который создает две пары каналов и разветвляет ребенка. Ребенок переводит свой STDIN в один канал, а STDOUT и STDERR в другой, затем запускает execlp() для запуска кода игры.

В игровом контроллере будет два потока. Первый будет блокировать в accept() на именованном сокете UNIX, получающем входные данные от другого приложения, а второй поток блокирует read(), отсылая канал ошибок и ошибок с игрового сервера.

Иногда первый поток получает команду на отправку строки в канал stdin игрового сервера. На этом этапе каким-то образом мне нужно остановить второй поток на read() ing, чтобы первый поток мог прочитать ответ из канала out и error.

(Стоит отметить, что я буду знать, сколько символов / строк длинно в ответе, поэтому я буду знать, когда прекратить чтение и позволить второму потоку возобновить чтение, сбрасывая процесс.)

Как временно переключить управление чтением на другой поток, как указано выше?

1 Ответ

4 голосов
/ 23 декабря 2011

Есть несколько вариантов.Один из них заключается в том, чтобы второй поток обрабатывал все показания и давал первому потоку способ дать ему сигнал, чтобы он передал входные данные обратно.Но это будет несколько сложно;вам нужно будет установить метод для сигнализации между потоками и убедиться, что первый поток сообщает второму потоку, что он хочет ввод, прежде чем второй поток прочитает его и обработает сам.Возможны различные типы состояний гонки, которые могут сделать ваш код непредсказуемым.

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

...