Установка settimer() и SIGALRM, когда условная переменная не сигнализируется

У меня есть несколько практических вопросов о settimer() и SIGALRM и о том, как они работают.

Допустим, у меня есть созданные темы: (ОТРЕДАКТИРОВАНО)

#define _POSIX_SOURCE
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <pthread.h>
#include <string.h>
#include <time.h>
#include <sys/time.h> 
#include <signal.h> 

pthread_mutex_t lock;
pthread_cond_t cond=PTHREAD_COND_INITIALIZER;

void timer_handler (int signum)
{
  printf ("\n[WAITING LINE] All our assistants are busy at the moment,we apologize. Please wait on the line\n");
}

void* threadFunc(void* arg){

        struct itimerval timer;
        if (signal(SIGALRM, (void (*)(int)) timer_handler) == SIG_ERR) {
            perror("Unable to catch SIGALRM");
            exit(1);
        }
        timer.it_value.tv_sec =1;
        timer.it_value.tv_usec = 0;


    while(mycond){
        if(setitimer (ITIMER_REAL, &timer, NULL)){
            perror("error calling setitimer()");
            exit(1);
        }

        pthread_cond_wait(&cond1,&lock);

        //doing other things that take significant time
    }


}

int main(){

//initializing mutex
....

//creating the threads
....
//waiting the threads to join
....
return 0;

}

Я не получаю сообщение, которое должно было отображаться каждые 20 мс. В примере, которому я следовал, while(1) было реализовано после установки таймера, но
я не могу этого сделать, потому что я хочу, чтобы это сообщение отображалось, пока мой поток ожидает сигнала условия. На самом деле не имеет значения, что реализовано в оставшемся коде, давайте предположим, что для завершения и сигнализации условия требуется гораздо больше времени, чем 20 мс.

Что мне делать, чтобы принимать сообщение timer_handler каждые 20 мс, пока условие еще не сигнализируется?

Я новичок в использовании как условных переменных, так и settimer(), поэтому буду признателен за любую помощь, чтобы понять их и решить любое недоразумение.


person Flora Biletsiou    schedule 05.05.2019    source источник


Ответы (1)


Если все ваши потоки заблокированы, часы виртуального таймера не будут работать. Возможно, вам придется переключиться на ITIMER_REAL. (Также имейте в виду, что вы не должны использовать небезопасные функции асинхронного сигнала, такие как printf внутри обработчика сигнала.)

person PSkocik    schedule 05.05.2019
comment
Я только что отредактировал код. Теперь я получаю сообщение только один раз и только в одном потоке. Я хочу получать это сообщение из каждого потока и несколько раз. Итак, как я могу это сделать? Кроме того, что я могу использовать вместо printf для моего обработчика таймера? - person Flora Biletsiou; 06.05.2019
comment
@FloraBiletsiou Если вам нужны повторяющиеся сигналы, установите it_interval в дополнение к it_value. Срабатывание сигнала в каждом потоке не так уж и тривиально, по крайней мере, я не могу придумать простое решение POSIX навскидку. printf можно заменить на write(1,...). - person PSkocik; 06.05.2019