views:

1469

answers:

4

As we know, doing things in signal handlers is really bad, because they run in an interrupt-like context. It's quite possible that various locks (including the malloc() heap lock!) are held when the signal handler is called.

So I want to implement a thread safe timer without using signal mechanism.

How can I do?

Sorry, actually, I'm not expecting answers about thread-safe, but answers about implementing a timer on Unix or Linux which is thread-safe.

+1  A: 

You should probably use something like pthreads, the POSIX threads library. It provides not only threads themselves but also basic synchronization primitives like mutexes (locks), conditions, semaphores. Here's a tutorial I found that seems to be decent: http://www.yolinux.com/TUTORIALS/LinuxTutorialPosixThreads.html

For what it's worth, if you're totally unfamiliar with multithreaded programming, it might be a little easier to learn it in Java or Python, if you know either of those, than in C.

David Zaslavsky
He is using threads ....
Tim Post
The OP asked how to implement a timer without using signals. Threads are not signals. I didn't see anything to suggest that he was using threads...
David Zaslavsky
A: 

Thread safe would imply a mutex or futex, are you sure that's what you meant? If you spend too much execution time negotiating either, check out the anti thread.

Tim Post
+1  A: 

I think the usual way around the problems you describe is to make the signal handlers do only a minimal amount of work. E.g. setting some timer_expired flag. Then you have some thread that regularly checks whether the flag has been set, and does the actual work.

If you don't want to use signals I suppose you'd have to make a thread sleep or busy-wait for the specified time.

janneb
+2  A: 

Use usleep(3) or sleep(3) in your thread. This will block the thread until the timeout expires.

If you need to wait on I/O and have a timer expire before any I/O is ready, use select(2), poll(2) or epoll(7) with a timeout.

If you still need to use a signal handler, create a pipe with pipe(2), do a blocking read on the read side in your thread, or use select/poll/epoll to wait for it to be ready, and write a byte to the write end of your pipe in the signal handler with write(2). It doesn't matter what you write to the pipe - the idea is to just get your thread to wake up. If you want to multiplex signals on the one pipe, write the signal number or some other ID to the pipe.

camh