Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Handling two threads, one sleeping and one waiting for input

Question: To create a program which takes user input but times out after some seconds (say it's 2 seconds for now).

Approach: I created two threads, one to wait for user input (inputThread with tid[0]) and other to sleep for 2 seconds (sleepThread with tid[1]). I cancel a thread from another thread's routine, as follows:

#include <stdio.h>
#include <unistd.h>
#include <pthread.h>

pthread_t tid[2];

void* inputThread()
{   
    int n;
    printf("Enter number:");

    // wait for input; if input is given then go ahead and cancel the sleeper thread.
    scanf("%d",&n); 

    // cancel the sleeper thread
    pthread_cancel(tid[1]); 

    printf("Got value:%d\n",n);
}

void* sleepThread()
{
    // sleep for 2 seconds and cancel the input thread.
    sleep(2); 

    // cancel the input thread
    pthread_cancel(tid[0]); 

    printf("\nNo value entered!\n");
}

int main(int argc, char const *argv[])
{
    int r1,r2,r3,r4;

    // input taking thread 
    r1 = pthread_create(&tid[0],NULL,inputThread,NULL); 

    // sleeping thread
    r2 = pthread_create(&tid[1],NULL,sleepThread,NULL);

    r3 = pthread_join(tid[0],NULL);
    r4 = pthread_join(tid[1],NULL);

    return 0;
}

As of now, the program works as expected.

But my friend says that it's not guaranteed to work since it depends on how threads are scheduled. He tried explaining the same to me but I couldn't understand. He also said that pthread_cancel is only a request to cancel the threads and it may not succeed.

So can someone please point out the potential mistake and best practice to avoid the same. Any changes to be made to guarantee the program's working is also appreciated.

like image 596
Rahul Bharadwaj Avatar asked Jan 29 '26 09:01

Rahul Bharadwaj


1 Answers

Your friend is right about the part that pthread_cancel is a request to the cancel the thread and might not succeed always.

For the part about scheduling you need to provide what arguments he had.

For a solution to your problem, you can abandon using threads all together (unless that is a requirement for your assignment) and use select with read.

This will make the solution not-portable (only conforming to POSIX), but pthreads is also anyway not portable.

select allows you to wait on a file descriptor (in this case 0) for data to be available for a read. It also allows you to set a timeout.

fd_set set;
FD_ZERO(&set);
FD_SET(0, &set);

struct timeval timeout;
timeout.tv_sec = 2;
timeout.tv_usec = 0;

int ret = select(1, &set, NULL, NULL, &timeout);

if (ret == 1) {
    char buffer[20];
    int n;
    read(0, buffer, 20);
    sscanf(buffer, "%d", &n);
    printf("Got value:%d\n",n);
} else {
    printf("Time out\n");
}
like image 52
Ajay Brahmakshatriya Avatar answered Jan 30 '26 23:01

Ajay Brahmakshatriya



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!