#c #linux #pthreads #user-input
#c #linux #pthreads #пользовательский ввод
Вопрос:
Я хотел бы получить значение от пользователя, т.Е. заданное значение для переменной, внутри цикла while, не блокируя выполнение других задач. Я пытаюсь использовать pthreads, и моя пробная версия привела к сбою. Несмотря на то, что я использую pthread, программа блокируется scanf
функцией.
Вот как я создаю pthread внутри функции main ()
uint16_t refAngle = 0;
char refAngleString[64];
int main(void)
{
pthread_t thread_id;
while(1) {
pthread_create(amp;thread_id, NULL, threadUserInput, NULL);
pthread_join(thread_id, NULL);
// Other functions were called below ...
}
}
Затем у меня есть функция потока с именем threadUserInput
void *threadUserInput(void* vargp)
{
scanf("%s", refAngleString);
refAngle = (uint16_t) atoi(refAngleString);
printf("Angle is: %dn", refAngle);
return NULL;
}
Любая помощь будет оценена, заранее спасибо.
Комментарии:
1. в этой функции:
threadUserInput()
отсутствует оператор:(void)vargp;
и оператор:return NULL;
должен быть:pthread_exit( NULL );
2. что касается:
scanf("%s", refAngleString);
Это не накладывает ограничений на длину слова, которое пользователю разрешено вводить, что может привести к переполнению входного буфера, что приводит к неопределенному поведению Для строки формата требуется модификатор MAX CHARACTERS, который на 1 меньше длины входного буфера, потому что ‘%s’ всегда добавляет NULбайт на ввод. Использование модификатора MAX CHARACTERS позволяет избежать любой возможности переполнения буфера и избежать любой возможности неопределенного поведения3. что касается: ` while(1) { pthread_create(amp;thread_id, NULL, threadUserInput, NULL); pthread_join(thread_id, NULL); // Другие функции были вызваны ниже … }` это приводит к тому, что программа останавливается каждый раз на протяжении цикла. Предлагаю:
pthread_create(amp;thread_id, NULL, threadUserInput, NULL); while(1) { // Other functions were called below ... } pthread_join(thread_id, NULL);
Затем измените функцию потока на цикл, а не на текущий одиночный проход4. Ваша последняя рекомендация сработала, спасибо!
5. Предложите использовать
pthread_mutex
so, чтобы условия гонки не приводили к тому, что поток вводил переменную, в то время как основная функция обрабатывает эту переменную
Ответ №1:
Несмотря на то, что я использую pthread, программа блокируется функцией scanf.
Ну, да. Созданный поток заблокирован scanf()
, а родительский поток заблокирован в pthread_join()
ожидании другого. У меня возникли проблемы с поиском какой-либо веской причины для запуска одного потока и последующего немедленного присоединения к нему, в отличие от простого прямого вызова функции потока.
Если вы хотите принимать пользовательский ввод один раз за итерацию цикла, но выполнять какую-то другую обработку (в рамках той же итерации), не дожидаясь этого ввода, то решение состоит в том, чтобы переместить pthread_join()
вызов мимо всей работы, которая может быть выполнена до получения пользовательского ввода:
while (1) {
pthread_create(amp;thread_id, NULL, threadUserInput, NULL);
// do work that does not require the user input ...
pthread_join(thread_id, NULL);
// do work that _does_ require the user input (if any) ...
}
В качестве альтернативы, возможно, вы ищете что-то еще более развязанное, когда цикл выполняет столько итераций, сколько ему нравится, пока ввод не станет доступным. В этом случае вы должны запустить поток ввода-вывода вне цикла и просто продолжать его выполнение, считывая ввод за вводом. Пусть он предоставит какой-то сигнал, когда есть ввод, доступный для использования основным потоком. Схематически это может выглядеть так:
pthread_create(amp;thread_id, NULL, threadAllUserInput, NULL);
while (1) {
// ... some work ...
if (get_input_if_available(/* arguments */)) {
// handle user input ...
}
// ... more work ...
}
force_input_thread_to_stop();
pthread_join(thread_id, NULL);
Я опускаю все подробности о том, как get_input_if_available()
и force_input_thread_to_stop()
может быть реализовано. Существует несколько альтернатив, некоторые из которых будут лучше соответствовать вашим конкретным потребностям, чем другие.