Hi I am writing a C program to interface a serial device which gives data at regular intervals, i need to look for the inputs at the serial port at regular intervals. this can be done by a ' read' function . but i dont know how to call it frequently at fixed time intervals ?
This sort of behavior short-circuits the lovely machinery built in to most OSes to do just this, failing that something like cron would seem to be a lovely option. Failing all of that (if you're just looking for a quick hacky option) busy wait is not super awesome, the system isn't bright enough to hyperthread around that so your program winds up eating up a core doing nothing for the duration of your program, so while it's largely a matter of taste, I'm a nanosleep man myself.
on nix/nux systems:
#include <time.h>
int main(void)
{
struct timespec sleepytime;
sleepytime.tv_sec = seconds_you_want_to_sleep
sleepytime.tv_nsec = nanoseconds_you_want_to_sleep
while( !done)
{
nanosleep(&sleepytime, NULL);
//do your stuff here
}
return 0;
}
if you're worried about getting interrupted, the second parameter should be another timespec struct, in which will be stored the amount of time remaining, check if == 0,
then keep on trucking.
in windows apparently it is a little easier.
#include <windows.h>
int main(void)
{
while( !done)
{
Sleep(milliseconds_you_want_to_sleep);
//do your stuff here
}
return 0;
}
Unfortunately I don't run windows so I haven't been able to test the second code sample.
If you really need to read at regular intervals ( and not just poll for data to be available ) , you can do something like this :
#include <signal.h>
#include <stdio.h>
#include <string.h>
#include <sys/time.h>
void timer_handler (int signum)
{
static int count = 0;
printf ("timer expired %d times\n", ++count);
}
int main ()
{
struct sigaction sa;
struct itimerval timer;
/* Install timer_handler as the signal handler for SIGVTALRM. */
memset (&sa, 0, sizeof (sa));
sa.sa_handler = &timer_handler;
sigaction (SIGVTALRM, &sa, NULL);
/* Configure the timer to expire after 250 msec... */
timer.it_value.tv_sec = 0;
timer.it_value.tv_usec = 250000;
/* ... and every 250 msec after that. */
timer.it_interval.tv_sec = 0;
timer.it_interval.tv_usec = 250000;
/* Start a virtual timer. It counts down whenever this process is
executing. */
setitimer (ITIMER_REAL, &timer, NULL);
/* Do busy work. */
while (1);
}
I copied this from http://www.informit.com/articles/article.aspx?p=23618&seqNum=14 and changed the timer type, effectively you are setting up an interval timer and handling the signal when the timer runs out.
Related
I am trying to get the memory consumed by an algorithm, so I have created a group of functions that would stop the execution in periods of 10 milliseconds to let me read the memory using the getrusage() function. The idea is to set a timer that will raise an alarm signal to the process which will be received by a handler medir_memoria().
However, the program stops in the middle with this message:
[1] 3267 alarm ./memory_test
The code for reading the memory is:
#include "../include/rastreador_memoria.h"
#if defined(__linux__) || defined(__APPLE__) || (defined(__unix__) && !defined(_WIN32))
#include <stdio.h>
#include <stdlib.h>
#include <sys/time.h>
#include <signal.h>
#include <sys/resource.h>
static long max_data_size;
static long max_stack_size;
void medir_memoria (int sig)
{
struct rusage info_memoria;
if (getrusage(RUSAGE_SELF, &info_memoria) < 0)
{
perror("Not reading memory");
}
max_data_size = (info_memoria.ru_idrss > max_data_size) ? info_memoria.ru_idrss : max_data_size;
max_stack_size = (info_memoria.ru_isrss > max_stack_size) ? info_memoria.ru_isrss : max_stack_size;
signal(SIGALRM, medir_memoria);
}
void rastrear_memoria ()
{
struct itimerval t;
t.it_interval.tv_sec = 0;
t.it_interval.tv_usec = 10;
t.it_value.tv_sec = 0;
t.it_value.tv_usec = 10;
max_data_size = 0;
max_stack_size = 0;
setitimer(ITIMER_REAL, &t,0);
signal(SIGALRM, medir_memoria);
}
void detener_rastreo ()
{
signal(SIGALRM, SIG_DFL);
printf("Data: %ld\nStack: %ld\n", max_data_size, max_stack_size);
}
#else
#endif
The main() function works calling all of them in this order:
rastrear_memoria()
Function of the algorithm I am testing
detener_rastreo()
How can I solve this? What does that alarm message mean?
First, setting an itimer to ring every 10 µs is optimistic, since ten microseconds is really a small interval of time. Try with 500 µs (or perhaps even 20 milliseconds, i.e. 20000 µs) instead of 10 µs first.
stop the execution in periods of 10 milliseconds
You have coded for a period of 10 microseconds, not milliseconds!
Then, you should exchange the two lines and code:
signal(SIGALRM, medir_memoria);
setitimer(ITIMER_REAL, &t,0);
so that a signal handler is set before the first itimer rings.
I guess your first itimer rings before the signal handler was installed. Read carefully signal(7) and time(7). The default handling of SIGALRM is termination.
BTW, a better way to measure the time used by some function is clock_gettime(2) or clock(3). Thanks to vdso(7) tricks, clock_gettime is able to get some clock in less than 50 nanoseconds on my i5-4690S desktop computer.
trying to get the memory consumed
You could consider using proc(5) e.g. opening, reading, and closing quickly /proc/self/status or /proc/self/statm etc....
(I guess you are on Linux)
BTW, your measurements will disappoint you: notice that quite often free(3) don't release memory to the kernel (thru munmap(2)...) but simply mark & manage that zone to be reusable by future malloc(3). You might consider mallinfo(3) or malloc_info(3) but notice that it is not async-signal-safe so cannot be called from inside a signal handler.
(I tend to believe that your approach is deeply flawed)
I am building a pre-emptive userspace thread scheduler which uses a timer to interrupt threads and switch between them according to priority. However, once a thread is interrupted, I cannot seem to let it finish; only start it again. Is what I am asking for even possible using swapcontext? The result of this code, which should allow itake5seconds() to complete, just loops the "Hello" message over and over.
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <time.h>
#include <sys/time.h>
#include <ucontext.h>
static ucontext_t mainc, newthread;
void itake5seconds()
{
puts("Hello. I take 5 seconds to run.");
sleep(5);
puts("And I'm done! Wasn't that nice?");
}
void timer_handler(int signum)
{
puts("Doing some scheduler stuff.");
swapcontext(&mainc, &newthread);
}
int main(int argc, char* argv[])
{
struct sigaction sa;
memset(&sa, 0, sizeof(sa));
sa.sa_handler = &timer_handler;
sigaction(SIGALRM, &sa, NULL);
getcontext(&newthread);
newthread.uc_stack.ss_sp = malloc(5000);
newthread.uc_stack.ss_size = 5000;
newthread.uc_link = &mainc;
makecontext(&newthread, &itake5seconds, 0);
struct itimerval timer;
timer.it_value.tv_sec = 0;
timer.it_value.tv_usec = 500000;
timer.it_interval.tv_sec = 0;
timer.it_interval.tv_usec = 500000;
setitimer(ITIMER_REAL, &timer, NULL);
while(1);
return 0;
}
Your code is calling an "unsafe" function in the signal handler (swapcontext). Therefor, the behavior of your program is "undefined".
From man 7 signal:
A signal handler function must be very careful, since processing elsewhere may be interrupted at some arbitrary point in the execution of the program. POSIX has the concept of "safe function". If a signal interrupts the execution of an unsafe function, and handler calls an unsafe function, then the behavior of the program is undefined.
See the "Example for SVID Context Handling" section in Complete Context Control for an example of how you can work this with a signal handler. But basically you'd use a volatile int global variable to flag that your signal handler was called and instead do the swapcontext call from normal code (i.e. code that's not running from within the context of signal handling).
The problem was that I was not saving the current execution context that swapcontext() returns to its first parameter.
We are trying to switch between multiple functions in our C program after saving the state using setjmp and longjmp but for only one function we are able to save the context not for other two functions. What could be the possible solution to it. Please suggest if necessary changes are required in the code.
In the o/p the state of fun1() is saved successfully in env1 and we are able to resume it back, but in case of fun2() and fun3() the state is not saved in the env2, env3.
Sample o/p:
i=0,j=999
i=1,j=998
i=2,j=997
i=3,j=996
ch=a
ch=b
ch=c
ch=d
a=0
a=-1
a=-2
a=-3
i=4,j=995/*The previous value of i is preserved*/
i=5,j=996
i=6,j=994
i=7,j=993
ch=<garbagevalue> /*The previous value of ch is lost*/
ch=<garbagevalue>
ch=<garbagevalue>
ch=<garbagevalue>
a=<garbagevalue> /*The previous value of ch is lost*/
a=<garbagevalue>
a=<garbagevalue>
a=<garbagevalue>
i=8,j=992
and so on..
Code follows:
#include <signal.h>
#include <stdio.h>
#include <string.h>
#include <sys/time.h>
#include<setjmp.h>
#define INTERVAL 5000
void fun1();
void fun2();
void fun3();
void timer_handler(int );
struct itimerval it_val;
jmp_buf env1,env2,env3;
int count=0;
void timer_handler (int signum)
{
if(count==0){
count++;
fun1();
}
if(count==1){
count++;
fun2();
}
if(count==2){
count++;
fun3();
}
L1:
if(count==3){
count++;
siglongjmp(env1,7);
}
if(count==4){
count++;
siglongjmp(env2,7);
}
if(count==5){
count++;
siglongjmp(env3,7);
}
count=3;
goto L1;
}
void fun1()
{
struct sigaction sa;
int i=0,j=999;
/* Install timer_handler as the signal handler for SIGVTALRM. */
memset (&sa, 0, sizeof (sa));
sa.sa_flags=SA_NODEFER;
sa.sa_handler = &timer_handler;
/* Configure the timer to expire after 250 msec... */
it_val.it_value.tv_sec = INTERVAL/1000;
it_val.it_value.tv_usec = (INTERVAL*1000) % 1000000;
it_val.it_interval.tv_sec = INTERVAL/1000;;
it_val.it_interval.tv_usec=(INTERVAL*1000) % 1000000;
sigaction (SIGALRM, &sa, NULL);
setitimer (ITIMER_REAL, &it_val, NULL);
while (1) {
while(sigsetjmp(env1,3)==0){
sleep(1);
printf("i=%d,j=%d\n",i,j);
i++;
j--;
}
}
}
void fun2()
{
struct sigaction sa;
char ch='a';
/* Install timer_handler as the signal handler for SIGVTALRM. */
memset (&sa, 0, sizeof (sa));
sa.sa_handler = &timer_handler;
sa.sa_flags=SA_NODEFER;
sigaction (SIGALRM, &sa, NULL);
/* Configure the timer to expire after 250 msec... */
it_val.it_value.tv_sec = INTERVAL/1000;
it_val.it_value.tv_usec = (INTERVAL*1000) % 1000000;
/* ... and every 250 msec after that. */
it_val.it_interval.tv_sec = INTERVAL/1000;;
it_val.it_interval.tv_usec=(INTERVAL*1000) % 1000000;
/* Start a virtual timer. It counts down whenever this process is*/
setitimer (ITIMER_REAL, &it_val, NULL);
/* Do busy work. */
while (1) {
while(sigsetjmp(env2,2)==0) {
sleep(1);
printf("ch=%c\n",ch);
if(ch=='z')
ch='a';
ch++;
}
}
}
void fun3()
{
struct sigaction sa;
int a=0;
/* Install timer_handler as the signal handler for SIGVTALRM. */
memset (&sa, 0, sizeof (sa));
sa.sa_handler = &timer_handler;
sa.sa_flags=SA_NODEFER;
sigaction (SIGALRM, &sa, NULL);
/* Configure the timer to expire after 250 msec... */
it_val.it_value.tv_sec = INTERVAL/1000;
it_val.it_value.tv_usec = (INTERVAL*1000) % 1000000;
/* ... and every 250 msec after that. */
it_val.it_interval.tv_sec = INTERVAL/1000;;
it_val.it_interval.tv_usec=(INTERVAL*1000) % 1000000;
/* Start a virtual timer. It counts down whenever this process is*/
setitimer (ITIMER_REAL, &it_val, NULL);
/* Do busy work. */
while (1){
while(sigsetjmp(env3,1)==0){
sleep(1);
printf("a=%d\n",a);
a--;
}
}
}
int main ()
{
timer_handler(1);
return 0;
}
You seem to be trying to implement some kind of threading without managing your stacks. This will not work. Ignoring the fact that pretty much everything in your code is undefined behavior, let's see what's actually going on.
You first call timer_handler(). This calls fun1. This sets a real time timer that will call timer_handler(). Then fun1 calls setjmp and sleeps. At this point your stack looks something like this:
timer_handler, fun1 (env1 points here), sleep
Now you get a SIGALRM. You execute timer_handler, this time count is 1, so you call fun2. It does more or less the same thing as fun1 and your stack looks like this:
timer_handler, fun1 (&env1), sleep, timer_handler, fun2 (&env2), sleep
One more SIGALRM. Stack looks like this:
timer_handler, fun1(&env1), sleep, timer_handler, fun2 (&env2), sleep, timer_handler, fun3 (&env3), sleep
One more SIGALRM, this is where the fun happens. You siglongjmp to env1. At this point your stack looks like this:
timer_handler, fun1
That's it. There might be stuff on the stack for fun2 and fun3 that might even work when you siglongjmp to them, but those parts are completely invalid now that you've rewound the stack pointer back to fun1. The call to printf seals the deal. Even if there might have been surviving parts on the stack that you could longjmp to, printf will definitely overwrite those parts.
Please suggest if necessary changes are required in the code.
The necessary changes are to delete the code, forget that setjmp and longjmp exist and never speak of this again. You can't do this. I've seen successful implementations of poor mans threads using setjmp and longjmp, but they also set up special stacks for the threads with sigaltstack, had proper locking and critical sections implemented and restricted the allowed functions calls to a very limited set of functions. Using printf when running such code is as far as you can get from having defined behavior. And all the successful implementations of this were of the "Look at this, isn't it horrible?" kind, not something anyone would ever use in real code.
Good Grief !!
I see you added the SA_NODEFER following your earlier question on this piece of code.
Mr POSIX says:
The interaction between setitimer() and alarm() or sleep() is unspecified.
That may be enough to stop this from working... but, frankly, it is so absolutely frightful that it does not deserve to work.
To fix this you need to take all the logic out of the signal action function. Signals are very, very nasty "software interrupts" and need to be handled very carefully, preferably with gloves, eye protection and steady hands. Unless this is homework for setjmp etc., I would treat those as even more nasty, and avoid touching them at all at all.
The main function is based on libevent, but there is a long run task in the function. So start N treads to run the tasks. Is is this idea OK? And how to use libevent and pthread together in C?
Bumping an old question, may have already been solved. But posting the answer just in case someone else needs it.
Yes, it is okay to do threading in this case. I recently used libevent in pthreads, and it seems to be working just fine. Here's the code :
#include <stdint.h>
#include <pthread.h>
#include <event.h>
void * thread_func (void *);
int main(void)
{
int32_t tid = 0, ret = -1;
struct event_base *evbase;
struct event *timer;
int32_t *t_ret = &ret;
struct timeval tv;
// 1. initialize libevent for pthreads
evthread_use_pthreads();
ret = pthread_create(&tid, NULL, thread_func, NULL);
// check ret for error
// 2. allocate event base
evbase = event_base_new();
// 3. allocate event object
timer = event_new(evbase, -1, EV_PERSIST, callback_func, NULL);
// 4. add event
tv.tv_sec = 0;
tv.tv_usec = 1000;
evtimer_add(timer, &tv);
// 5. start the event loop
event_base_dispatch(evbase); // event loop
// join pthread...
// 6. free resources
event_free(timer);
event_base_free(evbase);
return 0;
}
void * thread_func(void *arg)
{
struct event *ev;
struct event_base *base;
base = event_base_new();
ev = event_new(base, -1, EV_PERSIST, thread_callback, NULL);
event_add(ev, NULL); // wait forever
event_base_dispatch(base); // start event loop
event_free(ev);
event_base_free(base);
pthread_exit(0);
}
As you can see, in my case, the event for the main thread is timer. The base logic followed is as below :
call evthread_use_pthreads() to initialize libevent for pthreads on Linux (my case). For windows evthread_use_window_threads(). Check out the documentation given in event.h itself.
Allocate an event_base structure on global heap as instructed in documentation. Make sure to check return value for errors.
Same as above, but allocate event structure itself. In my case, I am not waiting on any file descriptor, so -1 is passed as argument. Also, I want my event to persist, hence EV_PERSIST . The code for callback functions is omitted.
Schedule the event for execution
Start the event loop
free the resources when done.
Libevent version used in my case is libevent2 5.1.9 , and you will also need libevent_pthreads.so library for linking.
cheers.
That would work.
In the I/O callback function delegates time consuming job to another thread of a thread pool. The exact mechanics depend on the interface of the worker thread or the thread pool.
To communicate the result back from the worker thread to the I/O thread use a pipe. The worker thread writes the pointer to the result object to the pipe and the I/O thread
wakes up and read the pointer from the pipe.
There is a multithreaded libevent example in this blog post:
http://www.roncemer.com/multi-threaded-libevent-server-example
His solution is, to quote:
The solution is to create one libevent event queue (AKA event_base) per active connection, each with its own event pump thread. This project does exactly that, giving you everything you need to write high-performance, multi-threaded, libevent-based socket servers.
NOTE This is for libev not libevent but the idea may apply.
Here I present an example for the community. Please comment and let me know if there are any noticable bugs. This example could include a signal handler for thread termination and graceful exit in the future.
//This program is demo for using pthreads with libev.
//Try using Timeout values as large as 1.0 and as small as 0.000001
//and notice the difference in the output
//(c) 2009 debuguo
//(c) 2013 enthusiasticgeek for stack overflow
//Free to distribute and improve the code. Leave credits intact
//compile using: gcc -g test.c -o test -lpthread -lev
#include <ev.h>
#include <stdio.h> // for puts
#include <stdlib.h>
#include <pthread.h>
pthread_mutex_t lock;
double timeout = 0.00001;
ev_timer timeout_watcher;
int timeout_count = 0;
ev_async async_watcher;
int async_count = 0;
struct ev_loop* loop2;
void* loop2thread(void* args)
{
// now wait for events to arrive on the inner loop
ev_loop(loop2, 0);
return NULL;
}
static void async_cb (EV_P_ ev_async *w, int revents)
{
//puts ("async ready");
pthread_mutex_lock(&lock); //Don't forget locking
++async_count;
printf("async = %d, timeout = %d \n", async_count, timeout_count);
pthread_mutex_unlock(&lock); //Don't forget unlocking
}
static void timeout_cb (EV_P_ ev_timer *w, int revents) // Timer callback function
{
//puts ("timeout");
if(ev_async_pending(&async_watcher)==false){ //the event has not yet been processed (or even noted) by the event loop? (i.e. Is it serviced? If yes then proceed to)
ev_async_send(loop2, &async_watcher); //Sends/signals/activates the given ev_async watcher, that is, feeds an EV_ASYNC event on the watcher into the event loop.
}
pthread_mutex_lock(&lock); //Don't forget locking
++timeout_count;
pthread_mutex_unlock(&lock); //Don't forget unlocking
w->repeat = timeout;
ev_timer_again(loop, &timeout_watcher); //Start the timer again.
}
int main (int argc, char** argv)
{
if (argc < 2) {
puts("Timeout value missing.\n./demo <timeout>");
return -1;
}
timeout = atof(argv[1]);
struct ev_loop *loop = EV_DEFAULT; //or ev_default_loop (0);
//Initialize pthread
pthread_mutex_init(&lock, NULL);
pthread_t thread;
// This loop sits in the pthread
loop2 = ev_loop_new(0);
//This block is specifically used pre-empting thread (i.e. temporary interruption and suspension of a task, without asking for its cooperation, with the intention to resume that task later.)
//This takes into account thread safety
ev_async_init(&async_watcher, async_cb);
ev_async_start(loop2, &async_watcher);
pthread_create(&thread, NULL, loop2thread, NULL);
ev_timer_init (&timeout_watcher, timeout_cb, timeout, 0.); // Non repeating timer. The timer starts repeating in the timeout callback function
ev_timer_start (loop, &timeout_watcher);
// now wait for events to arrive on the main loop
ev_loop(loop, 0);
//Wait on threads for execution
pthread_join(thread, NULL);
pthread_mutex_destroy(&lock);
return 0;
}
Can someone help me to complete my code with a function that can check the result of a timer "check_timer" and another one that reset this timer if it had expired "reset_timer"?
#include <pthread.h>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include <pthread.h>
#include <errno.h>
#include <sys/time.h>
#define GLOBAL_TIMER 8 * 60 * 60
typedef struct protocol_type {
int protocol_number;
char *protocol_name;
pthread_t thread_timer_id;
} protocol_type_t;
pthread_mutex_t mut = PTHREAD_MUTEX_INITIALIZER;
pthread_cond_t cond = PTHREAD_COND_INITIALIZER;
/* call back function - inform the user the time has expired */
void timeout_call_back(pthread_t thread_id)
{
printf("Welcome thread %ld, your time is up ===\n", pthread_self());
// doing some other stuff
}
/* Go to sleep for a period of seconds */
static void* start_timer(void *args)
{
/* function pointer */
void (*finish_function)(pthread_t);
int seconds = *((int*) args);
finish_function = timeout_call_back;
struct timeval now;
struct timespec timeout;
pthread_mutex_lock(&mut);
printf("thread ID : %ld, are waiting for %d seconds to to expire\n", pthread_self(), seconds);
gettimeofday(&now, NULL);
timeout.tv_sec = now.tv_sec + seconds;
timeout.tv_nsec = now.tv_usec * 1000;
pthread_cond_timedwait(&cond, &mut, &timeout);
(*finish_function)(pthread_self());
pthread_mutex_unlock(&mut);
pthread_exit(NULL);
}
// This function is in MT environnement and is running inside a daemon
int received_buffer_parser(char *received_buffer) {
pthread_mutex_t mut_main = PTHREAD_MUTEX_INITIALIZER;
protocol_type_t *my_protocol;
// Identify protocol type
my_protocol = protocol_identifier(received_buffer);
// Check if i received it in the last 8 hours in safe
pthread_mutex_lock(&mut_main);
if (check_timer(my_protocol->thread_id) has expired) { // I want to write this function
// I want to reset thread timer
launch_new_timer(my_protocol->thread_id)
}
else {
// doing some stuff
// dump data to the disk
}
pthread_mutex_unlock(&mut_main);
return 0;
}
int launch_new_timer(pthread_t thread_id)
{
int rc;
int seconds = GLOBAL_TIMER;
rc = pthread_create(&thread_id, NULL, start_timer, (void *) &seconds);
if(rc)
printf("Failed to create thread1\n");
pthread_join(thread_id, NULL);
return 0;
}
Clarification
I clarify here the real context of my code:
I receive from the network some types of different protocols packets(ICMP, SSH, RIP, OSPF, BGP...), and i want to:
identify every type of packets, let say with : identify_protocol(char *received_buffer), I got this function, it's ok.
Check if i receive this type of protocols in the last 8 hours (THE TIMER OF EACH PROTOCOL TYPE EXPIRE AFTER 8 HOURS), two choices:
a. if so, I dump the result data into a specific file on the disk.
b. no, I didn't receive this type in the last 8 HOURS i create a new thread (in my code i simplify, with thread1, thread2 and thread3, this threads are 3 threads used to be a timers for three protocols types) - i start a new timer with : start_timer(void *args) function do this job.
My main question is how to be able to check the result of my timers in a safe manner and then decide i reset the timer or not.
I design the finish_function at the beginning to help me to check when the timer has expired.
Feel free to give me a better design for best performances for my program.
My system is Linux.
To check for timers that merely expire, you don't need to use threads and synchronization at all. Simply keep global variables indicating the start time of the timer. So
when the timer starts, set a global variable (one per protocol) to gettimeofday()
when you want to check whether the timer has expired for a protocol, see whether gettimeofday()-starttime(protocol) is <8h
If you want to be notified on timer expiry, I recommend to use alarm(2). It only has second resolution, but that should be good enough for 8h timeouts. Whenever a timer is set, cancelled, or reset, compute the minimum timeout of any of the timers, then call alarm with that timeout. In the signal handler, perform the processing that you want to do on reception of timeout. Alternatively, do nothing in the signal handler, and just trust that any pending system call will be interrupted, and check all timers for expiry on EINTR.
Edit: alarm works like this
#include <unistd.h>
#include <signal.h>
void timeout(int ignored)
{
printf("timed out\n");
}
void main()
{
signal(SIGALRM, timeout);
alarm(10);
pause();
}