Linux C timer - signal disrupts current process

Viewed 100

I'm working on a application that has specific timing restraints such that an event should occur (ideally exactly) every 200us. I'm trying to do this with a timer and signal.

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

timer_t timer_id;

void start_timer(void)
{
    struct itimerspec value;

    value.it_value.tv_sec = 0;
    value.it_value.tv_nsec = 20000;

    value.it_interval.tv_sec = 0;
    value.it_interval.tv_nsec = 200000;

    timer_create(CLOCK_REALTIME, NULL, &timer_id);
    timer_settime(timer_id, 0, &value, NULL);
}

void handler(int sig) {
     printf("in handler\n");
}

void *my_thread(void *ignore)
{
    (void)ignore;

    start_timer();
    // Sleep forever
    while(1) sleep(1000);
}

int main()
{
    pthread_t thread_id;

    (void) signal(SIGALRM, handler);
    pthread_create(&thread_id, NULL, my_thread, NULL);
    // sleep is a placeholder for this SO question.  I want to do 
    // other processing here
    sleep(5000);
    printf("sleep finished\n");
}

After 200us the signal handler is called. It appears to be called when the sleep(5000) line is running because the "sleep finished" message is displayed early. I want the timer to disrupt the thread that started the timer, not the main process. This is why I created a thread to start it. Is there a way to have the signal only abort the current instruction on the thread instead of on the main process? I know that the other threads/processes will be blocked when the handler runs, but I wanted them to continue afterwards as if nothing happened. For example, in this case I want to sleep at least 5000 seconds.

1 Answers

Yes, you can block the signal (pthread_sigmask) in the main thread before starting any other threads, and only unblock it in the thread intended to handle it. This will ensure that it arrives in the thread you want it in.

However, if you already have threads, are you sure you actually need a timer generating a signal for this? clock_nanosleep should allow sleep with wakeup at a precise time, and avoids all the awfulness of signals.

Related