0

I would like to get a value from the user, i.e. setpoint for a variable, inside a while loop without blocking other tasks to perform. I am trying to use pthreads and my trial resulted in a failure. Even though I am utilizing pthread, the program is blocked by the scanf function.

This is how I create the pthread inside the main() function

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 ...
   }
}

Then I have the thread function named threadUserInput

void *threadUserInput(void* vargp)
{
    scanf("%s", refAngleString);
    refAngle = (uint16_t) atoi(refAngleString);
    printf("Angle is: %d\n", refAngle);

    return NULL;
}

Any help would be appreciated, thanks in advance.

7
  • this function: threadUserInput() is missing the statement: (void)vargp; and the statement: return NULL; should be: pthread_exit( NULL ); Commented Apr 11, 2019 at 20:23
  • regarding: scanf("%s", refAngleString); This places no limit on the length of the word that the user is allowed to enter, which can result in a input buffer overflow which results in undefined behavior The format string needs a MAX CHARACTERS modifier that is 1 less than the length of the input buffer, because '%s' always appends a NUL byte to the input. Using the MAX CHARACTERS modifier avoids any possibility of a buffer overflow and avoids any possibility of undefined behavior Commented Apr 11, 2019 at 20:28
  • 1
    regarding: ` while(1) { pthread_create(&thread_id, NULL, threadUserInput, NULL); pthread_join(thread_id, NULL); // Other functions were called below ... }` this results in the program stopping every time through the loop. Suggest: pthread_create(&thread_id, NULL, threadUserInput, NULL); while(1) { // Other functions were called below ... } pthread_join(thread_id, NULL); Then modifying the thread function to loop rather than the current single pass Commented Apr 11, 2019 at 20:31
  • Your latest recommendation worked, thanks! Commented Apr 11, 2019 at 20:36
  • Suggest using a pthread_mutex so no race conditions result in the thread inputting a variable while the main function is processing that variable Commented Apr 11, 2019 at 20:37

1 Answer 1

2

Even though I am utilizing pthread, the program is blocked by the scanf function.

Well, yes. The created thread is blocked in scanf(), and the parent thread is blocked in pthread_join(), waiting for the other. I'm having trouble coming up with any good reason for launching a single thread and then immediately joining it, as opposed to simply calling the thread function directly.

If you want to take user input once per iteration of the loop, but perform some other processing (within the same iteration) without waiting for that input, then the solution is to move the pthread_join() call past all the work that can be done before the user input is received:

   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) ...
   }

Alternatively, perhaps you're looking for something even more decoupled, with the loop churning through as many iterations as it likes until input becomes available. In that case, you should start the I/O thread outside the loop and just keep it running, reading input after input. Have it provide some kind of signal when there is input available for the main thread to consume. Schematically, that might look like this:

   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);

I omit all details of how get_input_if_available() and force_input_thread_to_stop() might be implemented. There are multiple alternatives, some of which will be better suited to your particular needs than are others.

Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.