2009-05-27 2 views
5

Есть ли рекомендуемый способ ожидания на нескольких входах. Например, я хотел бы, чтобы моя программа могла получать входные данные из 3 источников:Ожидание нескольких событий C++

Слушайте условия нити, например. pthread_cond_wait()

Принимать данные со стандартного ввода, например. getline()

Слушайте в розетке, например. accept()

Каков наилучший способ для этого? Нужен ли поток для каждого источника входных данных? Спасибо

+0

Да, причина этого, вероятно, не нужна. У меня должен быть основной поток, ожидающий только при условии. Поток «Внешний вход» с помощью select() для ожидания ввода сокета и файла. Тогда как дочерние потоки, так и поток «внешнего ввода» могут стимулировать основной поток, используя условие. –

ответ

4

Вы можете прослушивать несколько дескрипторов файла без использования нескольких потоков с использованием системного вызова select(2). Вы можете использовать pthread_cond_timedwait для ожидания переменной состояния с тайм-аутом, чтобы вы не ждали больше определенного времени.

Я думаю, что очень необычно хотеть одновременно ждать либо переменной условия, либо какого-либо дескриптора файла - если вы абсолютно уверены, что это то, что вы хотите сделать, вам придется использовать несколько потоков , причем один поток вызывает либо pthread_cond_wait/pthread_cond_timedwait, и другой поток, вызывающий select или какую-либо другую функцию ввода-вывода.

+8

Это просто необычно, потому что вы не можете сделать это (легко) на unixes. Это очень часто встречается в win32, где ожидание на нескольких вещах (дескрипторы сокетов, очереди потоков, семафоры и многое другое) не вызывает затруднений. – nos

0

Конечно, кажется, что эти три разных варианта обмена сообщениями являются взаимоисключающими для одного потока; как может один поток читать из stdin, пока он ждет условия потока?

Если вы действительно не хотите создавать три потока, единственный вариант, который я могу понять, - это каким-то образом модифицировать или параметризовать библиотеки потоков, потоков и сокетов, чтобы получить ссылку на объект синхронизации.

7

Нет необходимости в отдельной ните в ожидании accept(2) и stdin - используйте poll/select здесь. Вместо условной переменной создайте канал между потоками (у вас уже есть потоки, если мы говорим о CV), подождите на нем в том же poll и напишите ему, когда произойдет событие.

3

В современной Linux лучший способ сделать это - не использовать pthread_cond_wait. Вместо этого используйте eventfd, что позволит вам прослушивать несколько событий с помощью select/poll/epoll.

Смежные вопросы