#include #include #include #include #include #include #include void abort_perror(const char *msg) { perror(msg); exit(1); } void *my_periodic_thread (void *cookie) { struct itimerspec its; struct sigevent sig; sigset_t blocked; siginfo_t si; timer_t mytimer; int i; /* create a timer that will be used to periodically send a signal */ sig.sigev_notify = SIGEV_SIGNAL; sig.sigev_signo = SIGUSR1; sig.sigev_value.sival_ptr = &sig; if(timer_create(CLOCK_REALTIME, &sig, &mytimer)) abort_perror("timer_create"); /* block the signal used by the timer */ sigemptyset(&blocked); sigaddset(&blocked, SIGUSR1); pthread_sigmask(SIG_BLOCK, &blocked, NULL); /* set the periodic timer */ its.it_value.tv_sec = 0; its.it_value.tv_nsec = 40000000; /* 40 ms */ its.it_interval.tv_sec = 0; its.it_interval.tv_nsec = 20000000; /* 20 ms */; if(timer_settime(mytimer, 0, &its, NULL)) abort_perror("timer_settime"); printf("periodic thread started...\n"); for (i=0; i<40; i++) { while (sigwaitinfo(&blocked, &si) == -1 && errno == EINTR); /* The thread body */ printf("%d\n",i); } printf("...periodic thread end!\n"); timer_delete(mytimer); return NULL; } int main() { pthread_t mythread; pthread_attr_t myattr; struct sched_param myparam; void *returnvalue; sigset_t blocked; /* block the signal used by the timer */ // REMOVE THE COMMENTS BELOW // sigemptyset(&blocked); // sigaddset(&blocked, SIGUSR1); // pthread_sigmask(SIG_BLOCK, &blocked, NULL); /* initializes the thread attribute */ pthread_attr_init(&myattr); pthread_attr_setinheritsched(&myattr, PTHREAD_EXPLICIT_SCHED); pthread_attr_setschedpolicy(&myattr, SCHED_FIFO); myparam.sched_priority = 3; pthread_attr_setschedparam(&myattr, &myparam); printf("starting a periodic thread...\n"); if (pthread_create(&mythread, &myattr, my_periodic_thread, NULL)) abort_perror("pthread_create"); pthread_attr_destroy(&myattr); /* wait the end of the thread we just created */ pthread_join(mythread, &returnvalue); printf("ending main...\n"); return 0; }