Gian
Gian

Reputation: 357

How do I make a thread stop another thread?

I've basically just found out that multithreading programming exists and I'm having fun blindly playing around with the concept.

What I'm trying to do is a timer that gets checked dynamically every second, while the user keeps interacting with the program in some form.

This is what I was able to accomplish so far:

void* timer (void* threadToStop)
{
    pthread_t* threadName = threadToStop;

    time_t startTime = time(NULL);
    time_t currentTime;
    int elapsedTime;
    int remainingTime;

    do {

        if (currentTime != time(NULL)) 
        {
            currentTime = time(NULL);
            elapsedTime = currentTime - startTime;
            remainingTime = 10 - elapsedTime;
            printf("%d ", remainingTime);
            fflush(stdout);
        }

    } while (remainingTime > 0);

    pthread_cancel(*threadName);

    return NULL;
}

void* func (void* vargp)
{
    getchar();

    return NULL;
}

int main(void)
{

    pthread_t funcId;
    pthread_create(&funcId, NULL, func, NULL);

    pthread_t timerId;
    pthread_create(&timerId, NULL, timer, &funcId);

    pthread_join(funcId, NULL); 

    return EXIT_SUCCESS;
}

Two threads get created from two different functions and start running concurrently.

"func" is just a dummy function that asks the user to input a character. It's just a way to have the user interacting with the program while the timer is running in the background.

"timer" is self-explanatory: it's the function that starts and updates the timer every second. When this thread gets created, it also gets func's thread id as an argument. When time's up, I call the pthread_cancel function in order to stop func's thread using its id.

This program works for the most part: the timer keeps running while I'm able to input characters in the console, and when I press the enter key the pthread_join function kicks in and the main function reaches the end. However, when the timer runs out, the func thread doesn't get cancelled and I'm having a hard time figuring out why.

Upvotes: 0

Views: 60

Answers (1)

alk
alk

Reputation: 70883

The code misses to initialise currentTime, before using it:

  time_t currentTime;
  int elapsedTime;
  int remainingTime;

  do {

    if (currentTime != time(NULL)) 

A thread only gets cancelled when passing or "sitting on" a so called Cancellation Point.

getchar() is not necessarily a cancellation point.

A list of mandatory and optional cancellation points for POSIX threads is here.


To shed some light on what is really going on replace:

  pthread_cancel(...);

by:

  errno = pthread_cancel(...);
  if (0 != errno)
  {
    perror("pthread_cancel() failed");
  }

Upvotes: 1

Related Questions