Нет разницы в чтении стандартного ввода из потоков, за исключением случаев, когда несколько потоков пытаются прочитать его одновременно. Скорее всего, ваши потоки - это не все вызывающие функции, которые постоянно читают стандартный ввод.
Если вам регулярно нужно читать ввод от пользователя, вам может понадобиться один поток, который просто читает этот ввод, а затем устанавливает флаги или публикует события в других потоках на основе этого ввода.
Если символ уничтожения - это единственное, что вам нужно, или если он будет использоваться только для отладки, то вам, вероятно, нужно время от времени запрашивать новые данные на стандартном вводе. Вы можете сделать это, настроив стандартный ввод как неблокирующий, и попытаться время от времени читать его. Если чтение возвращает 0 символов, то ни одна клавиша не была нажата. У этого метода есть некоторые проблемы. Я никогда не использовал stdio.h функций на FILE *
после того, как установил базовый файловый дескриптор (int) на неблокирующую, но подозреваю, что они могут действовать странно. Вы можете избежать использования функций stdio и использовать read
, чтобы избежать этого. Есть одна проблема, о которой я читал один раз, когда флаг блока / неблокирования мог быть изменен другим процессом, если вы разветвляли и исполняли новую программу, которая имела доступ к версии этого дескриптора файла. Я не уверен, если это проблема во всех системах. Неблокирующий режим можно установить или сбросить с помощью вызова fcntl.
Но вы могли бы использовать одну из функций опроса с очень маленьким (0) таймаутом, чтобы посмотреть, готовы ли данные. Системный вызов poll
, вероятно, самый простой, но есть и select
. Различные операционные системы имеют другие функции опроса.
#include <poll.h>
...
/* return 0 if no data is available on stdin.
> 0 if there is data ready
< 0 if there is an error
*/
int poll_stdin(void) {
struct pollfd pfd = { .fd = 0, .events = POLLIN };
/* Since we only ask for POLLIN we assume that that was the only thing that
* the kernel would have put in pfd.revents */
return = poll(&pfd, 1, 0);
}
Вы можете вызывать эту функцию в одном из ваших потоков до тех пор, пока она не перенастроится на 0, а вы просто продолжите. Когда он возвращает положительное число, вам нужно прочитать символ из stdin, чтобы увидеть, что это было. Обратите внимание, что если вы используете функции stdio в stdin
в других местах, на самом деле могут быть другие символы, уже помещенные в буфер перед новым персонажем. poll
говорит вам, что в операционной системе есть что-то новое для вас, а не то, что есть у stdio в C.
Если вы регулярно читаете со стандартного ввода в других темах, то все становится беспорядочным. Я предполагаю, что вы этого не делаете (потому что, если вы работаете правильно, вы, вероятно, не задавали бы этот вопрос).