Как заставить поток остановить другой поток? - PullRequest
0 голосов
/ 12 мая 2019

Я в основном только что узнал, что многопоточное программирование существует, и мне весело слепо поиграть с этой концепцией.

То, что я пытаюсь сделать, это таймер, который проверяется динамически каждую секунду, в то время как пользователь продолжает взаимодействовать с программой в той или иной форме.

Это то, что мне удалось сделать до сих пор:

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

Два потока создаются из двух разных функций и запускаются одновременно.

"func" - это просто фиктивная функция, которая просит пользователя ввести символ.Это просто способ взаимодействия пользователя с программой, когда таймер работает в фоновом режиме.

"timer" не требует пояснений: это функция, которая запускает и обновляет таймер каждую секунду.Когда этот поток создается, он также получает идентификатор потока func в качестве аргумента.Когда время истекло, я вызываю функцию pthread_cancel, чтобы остановить поток func, используя его идентификатор.

Эта программа работает по большей части: таймер продолжает работать, пока я могу ввестисимволов в консоли, и когда я нажимаю клавишу ввода, включается функция pthread_join, и основная функция достигает конца.Однако, когда таймер заканчивается, поток func не отменяется, и мне трудно понять, почему.

1 Ответ

1 голос
/ 12 мая 2019

Код не инициализируется currentTime, прежде чем его использовать:

  time_t currentTime;
  int elapsedTime;
  int remainingTime;

  do {

    if (currentTime != time(NULL)) 

Поток отменяется только при прохождении или "сидении" на так называемой Точке отмены .

getchar() не обязательно является точкой отмены.

Список обязательных и необязательных точек отмены для потоков POSIX: здесь .


Чтобы пролить свет на то, что действительно происходит, замените:

  pthread_cancel(...);

по:

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