I have some practical questions about the settimer() and SIGALRM and how they work .
Let's say that I have some threads created: (EDITED)
#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;
}
I don't get the message I was supposed to see displayed every 20 msec.
In the example I followed a while(1) was implemented after the settimer but
I can't do that because I want this message displayed while my thread waits for the condition signal.
It doesn't really matter what is implemented in the rest code , let's assume it takes far more time than 20ms to finish and signal the condition.
What should I do to take the timer_handler message every 20ms while the condition is not signaled yet?
I am new to using both condition variables and settimer() so any help to understand them and solve any misunderstaning would be appreciated .
If all your threads are blocked, the virtual timer's clock will not be running.
You might need to switch to ITIMER_REAL. (Also beware that you shouldn't be using async-signal unsafe functions such as printf inside a signal handler.)
Related
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.
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.
I am using eclipse IDE on ubuntu to compile my c project. I have a timer. After starting the timer, sleep or usleep functions are not working.
Here is the code;
EDIT
/*
============================================================================
Name : TimerTest.c
Author : FK
Version :
Copyright : Your copyright notice
Description : Hello World in C, Ansi-style
============================================================================
*/
#include <stdio.h>
#include <stdlib.h> /* , getenv() */
#include <getopt.h>
#include <unistd.h> /* exec(), daemon() */
#include <stdint.h>
#include <string.h> /* memset(), strerror() */
#include <errno.h> /* errno */
#include <libgen.h> /* basename() */
#include <signal.h>
#include <sys/timex.h> /* ntp_gettime() */
#include <time.h>
#include "timer/timer.h"
#define CONFIG_TIMER_INTERVAL 100 /* in ms */
/* global vars decalarations */
static uint8_t _terminate = 0;
static int _signo = 0;
static int init_prg(int argc, char *argv[]);
static void timer_callback(void);
/* function implementations */
static void sig_handler(int signo)
{
/* http://www.yolinux.com/TUTORIALS/C++Signals.html */
_signo = signo;
switch (signo)
{
case SIGINT: /* Program interrupt. (ctrl-c) */
_terminate = 1;
break;
case SIGTERM:
_terminate = 1;
break;
/* SIGKILL, SIGSTOP yakalanımıyor! */
default:
break;
}
}
int main(int argc, char *argv[])
{
init_prg(argc, argv);
/* start super loop */
while (1)
{
printf("test!\n");
//usleep(1000000);
sleep(1);
}
}
static int init_prg(int argc, char *argv[])
{
int res = -1;
if (signal(SIGINT, sig_handler) == SIG_ERR)
{
//exit(EXIT_FAILURE);
}
/* Termination, Generated by "kill" command. */
if (signal(SIGTERM, sig_handler) == SIG_ERR)
{
//exit(EXIT_FAILURE);
}
start_timer(2000, &timer_callback);
if (res != 0)
{
//exit(EXIT_FAILURE);
}
return res;
}
static void timer_callback(void)
{
printf("timer works!\n");
}
after execute program, it echoes "test!" rapidly. Ignoring sleep or usleep commands. if I comment out start_timer line, it sleeps, after timer it is not.Any ideas?
You're not showing what standardized intefaces you're using to start the timer.
Regardless, POSIX specifies that the interaction of usleep with
nanosleep()
setitimer()
timer_create()
timer_delete()
timer_getoverrun()
timer_gettime()
timer_settime()
ualarm()
sleep()
is unspecified.
nanosleep should not have that problem.
From nanosleep's manpage:
Compared to sleep(3) and usleep(3), nanosleep() has the following
advantages: it provides a higher resolution for specifying the sleep
interval; POSIX.1 explicitly specifies that it does not interact with
signals; and it makes the task of resuming a sleep that has been
interrupted by a signal handler easier.
The above suggests that replacing your usleep with:
#include <unistd.h>
int my_usleep(useconds_t Usec);
#include <time.h>
int my_usleep(useconds_t Usec)
{
return nanosleep(&(const struct timespec){
.tv_sec = Usec/100000, .tv_nsec=1000*Usec%1000000}, NULL);
}
should fix the problem.
It seems you are using a timer library similar to the one available at https://www.teuniz.net/Timer_code/ . If you open timer.c in that library, you will see that it uses setitimer(ITIMER_REAL, ...). A timer created in this way will generate a SIGALRM whenever the timer expires. This, in turn, will wake your program from sleep()ing.
Why? Because, if you read the POSIX specification for sleep() (available at http://pubs.opengroup.org/onlinepubs/009695399/ -> Alphabetical index -> sleep()), you will read.
The sleep() function shall cause the calling thread to be suspended from execution until either the number of realtime seconds specified by the argument seconds has elapsed or a signal is delivered to the calling thread and its action is to invoke a signal-catching function or to terminate the process.
If, on the other hand, you are not using the afore-mentioned library, then you need to show exactly what your start_timer() function is doing. Otherwise, anyone who tries to help you is shooting in the dark.
Solution: threads
I think your only option is to use separate threads - one thread for the task that sleeps and another for the task that handles the timer.
#include <stdio.h>
#include <pthread.h>
#include <signal.h>
#include <semaphore.h>
#include <time.h>
#include <stdlib.h>
#include <errno.h>
#include <unistd.h>
#define NUM_THREADS 2
sem_t mutex;
pthread_t tid[NUM_THREADS];
void *thr_generator();
void *thr_handler();
int main(){
sem_init(&mutex,0,1);
pthread_create(&tid[1],NULL,thr_handler,NULL);
pthread_create(&tid[0],NULL,thr_generator,NULL);
int i;
for(i=0;i<2;i++){
pthread_join(tid[i],NULL);
}
sem_destroy(&mutex);
}
void *thr_generator(){
int i;
for(i=0;i<10;i++){
pthread_kill(tid[1],SIGUSR1);
sleep(1);
}
}
void *thr_handler(){
sigset_t sig_set;
sigemptyset(&sig_set);
int i;
int sig;
sigaddset(&sig_set,SIGUSR1);
pthread_sigmask(SIG_BLOCK,&sig_set,NULL);
while(1){
printf("Waiting on a signal...\n");
if((i=(sigwaitinfo(&sig_set,NULL)))==10){
printf("signal received\n");
}
else{
printf("The set is empty\n");
exit(0);
//break;
}
printf("%d\n",i);
}
pthread_sigmask(SIG_UNBLOCK,&sig_set,NULL);
}
Above is my entire test code for reference.
For testing purpose, I created 2 threads, in which one send SIGUSR1 to the other, which handles the signal.
My question is regarding specifically the thr_handler function.
When I compile this code and run it, I would get the output of
Waiting on a signal...
signal received
.
. (meaning the same output repeats x number of times according to the generator loop)
.
Waiting on a signal... (stuck here)
If my understanding is correct, sigwaitinfo() function inside thr_handler is suspending the handling thread and there is no way to resume the thread unless another signal is received by it. What can I do so that I can check to see if the signal queue is empty and break out of the loop? Is there a way to check to see if the queue of signals is empty?
Also, initially, I planned to use sleep() on some random number between .01 and .1 in every iteration of generator loop. Is this enough of a delay so that all signals are received by the handler thread? When I was testing my code using a generator loop of 10000, it seemed to me that the handler only received about 100 or less signals according to the output.
In this part of your code
if((i=(sigwaitinfo(&sig_set,NULL)))==10){
printf("signal received\n");
}
You should check to see which signal is being sent, SIGUSR1
so it would be:
if(sigwaitinfo(&sig_set,NULL) == SIGUSR1){
printf("signal received\n");
}
You have sent 10 signals, therefore 10 SIGUSR1 will be received.
You have only one thread running the handler which is safe. However, if later you want to generate more than one thread to run the handler, there will be synchronization problems and more code will be needed.
I would like to have a function run periodically, given a time step. What is the most efficient way to do this?
I know I could use a while look and just keep checking till the dt period has elapsed. But I'd like to know if there is a better, more efficient/elegant function to use.
I was looking into virtual timers and sigaction. Using this method, I would have the sigaction handler set a flag when the time has elapsed, but I would still need to sit in a while loop checking for that flag to be set in my main function. Alternatively I wonder if I could actually have the handler run the function, but then I would have to pass a lot of arguments, and as far as I have read, handlers don't take arguments, so I would have to use lots of global variables.
What would be the best way to tackled this?
On an *IX'ish system you could
install a handler for SIGALRM, which does nothing
set an alarm using alarm()
call blocking pause()
If the alarm signal is sent pause() will return and
you can run the function in question,
again set the alarm
start over calling pause()
#define _POSIX_SOURCE 1
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <unistd.h>
#include <signal.h>
#include <errno.h>
void handler_SIGALRM(int signo)
{
signo = 0; /* Get rid of warning "unused parameter ‘signo’" (in a portable way). */
/* Do nothing. */
}
int main()
{
/* Override SIGALRM's default handler, as the default handler might end the program. */
{
struct sigaction sa;
memset(&sa, 0, sizeof(sa));
sa.sa_handler = handler_SIGALRM;
if (-1 == sigaction(SIGALRM, &sa, NULL ))
{
perror("sigaction() failed");
exit(EXIT_FAILURE);
}
}
while (1)
{
alarm(2); /* Set alarm to occur in two seconds. */
pause(); /* The call blocks until a signal is received; in theis case typically SIGARLM. */
/* Do what is to be done every 2 seconds. */
}
return EXIT_SUCCESS;
}
The easiest way is to use sleep or usleep as defined in unistd.h.
If neither of those are available then a common workaround is to use a select with a timeout on no file descriptors.
Include time.h and use sleep function like
#include <time.h>
#include <stdio.h>
#include<windows.h>
#include <conio.h>
int main() {
printf("I am going to wait for 4 sec");
Sleep(4000); //sleep for 4000 microsecond= 4 second
printf("Finaaly the wait is over");
getch();
return 0;
}
It will give you a precise delay on microsecond level.
Hope it helped.
Revisiting this question:
I have multiple threads running (pthreads api), each with it's own timer that calls a function handler(int signum) after a certain interval. As these threads call handler and within the function handler, how do I know which thread called it? Is thread-specific data required?
I notice that the thread that enters the handler function is a different thread from the one that set it up, so calling pthread_self() doesn't work. How do I get around this?
Here is a small example illustrating the problem
#include <pthread.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/time.h>
#include <sys/types.h>
#include <sys/wait.h>
#include <time.h>
#include <unistd.h>
void handler(int);
void call_alarm();
void *setup(void*);
pthread_t p;
void handler(int signum)
{
printf("handler thread %lu\n", pthread_self());
}
void call_alarm()
{
static struct itimerval timer;
static struct sigaction sa;
printf("call_alarm %lu\n", (unsigned long)pthread_self());
sa.sa_handler = handler;
sa.sa_flags = SA_RESETHAND;
timer.it_value.tv_usec = 500;
timer.it_value.tv_sec = 0;
timer.it_interval.tv_sec = 0;
timer.it_interval.tv_usec = 0;
sigaction(SIGALRM, &sa, 0);
setitimer(ITIMER_REAL, &timer, 0);
}
void *setup(void *param)
{
while(1)
{
printf("caller thread %lu\n", pthread_self());
call_alarm();
pause();
}
}
int main(void)
{
if(pthread_create(&p, NULL, setup, NULL));
while(1);
return 0;
}
Output:
caller thread 3086637968
call_alarm 3086637968
handler thread 3086640832
As you can see it prints out different values.
You can print the thread ID when the handler is called:
On Linux: gettid()
On Windows GetCurrentThreadId().
and if you can't, write a function wrapper around the handler and tell your code to call the wrapper function instead of calling the handler directly.
The POSIX chapter on Signal Generation and Delivery states:
At the time of generation, a determination shall be made whether the signal has been generated for the process or for a specific thread within the process. Signals which are generated by some action attributable to a particular thread, such as a hardware fault, shall be generated for the thread that caused the signal to be generated. Signals that are generated in association with a process ID or process group ID or an asynchronous event, such as terminal activity, shall be generated for the process.
I wonder if the SIGALRM signal you're catching is not considered a action attributable to a particular thread, such as a hardware fault. It sounds like your SIGALRM signal falls into the second category, and is being generated for the process.