Получить пользовательский ввод без блокировки в то время как цикл с использованием потоков в C - PullRequest
0 голосов
/ 11 апреля 2019

Я хотел бы получить значение от пользователя, то есть заданное значение для переменной, внутри цикла while, не блокируя другие задачи для выполнения.Я пытаюсь использовать pthreads, и мое испытание завершилось неудачей.Даже если я использую pthread, программа блокируется функцией scanf.

Так я создаю pthread внутри функции main ()

uint16_t refAngle = 0;
char refAngleString[64];

int main(void)
{
   pthread_t thread_id;

   while(1) {
       pthread_create(&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: %d\n", refAngle);

    return NULL;
}

Любая помощь будет оценена, спасибо заранее.

1 Ответ

1 голос
/ 12 апреля 2019

Несмотря на то, что я использую pthread, программа блокируется функцией scanf.

Ну, да.Созданный поток заблокирован в scanf(), а родительский поток заблокирован в pthread_join(), ожидая другого.У меня возникают проблемы с поиском какой-либо веской причины для запуска одного потока и последующего немедленного присоединения к нему, в отличие от простого непосредственного вызова функции потока.

Если вы хотите принимать ввод пользователя один раз за итерациюцикл, но выполнить некоторую другую обработку (в пределах той же итерации), не ожидая этого ввода, тогда решение состоит в том, чтобы переместить вызов pthread_join() за всю работу, которая может быть выполнена до получения ввода пользователя:

   while (1) {
       pthread_create(&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(&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() могут быть реализованы.Существует несколько альтернатив, некоторые из которых будут лучше соответствовать вашим конкретным потребностям, чем другие.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...