I am implementing a program that uses threads. I want Each created thread to be delayed for a time. Then a signal is sent to the thread, and the handler should print a message. My issue is in sending a signal to a thread. how could it be possible to send an alarm signal to each thread created?
I can use pthread_kill(), but how could I specify the time as in alarm(6) or so on?
void *thread(void *parameter)
{
//How to send a signal to a thread
}
void threadHandler(int sig)
{
printf("hello from thread\n");
}
Well, one possibility would be to make an additional thread which sleeps for a given amount of time using e.g. usleep and then uses pthread_kill to send the signal you want to send to the correct thread. If you e.g. want to send three signals, after 1, 3 and 5 seconds have passed, you can use this code:
usleep(1*1000*1000);
pthread_kill(thread1, SIGALRM);
usleep(2*1000*1000);
pthread_kill(thread2, SIGALRM);
usleep(2*1000*1000);
pthread_kill(thread3, SIGALRM);
If you're on Linux, you can use timerfd_create() to create a timer file descriptor from which data can be read after the given amount of time has passed. So, if you have e.g. 10 threads, you can create 10 timerfds with the thread-specific timeout and then use an epoll_wait() loop (see epoll_create and epoll_wait manual pages) which listens for data to be read from the timerfds and sends the signal to the correct thread once there is data to be read.
I don't think there is any ready-made interface that sends a SIGALRM signal to a specific thread after a specific amount of time has passed, but if creating an extra thread is an option you can definitely emulate it using usleep() or timerfd_create() / epoll_wait().
Related
I have a 'C' application in linux where in i have register SIGALRM handler. My SIGALRM handler updates some global data that other threads are also accessing.
Requirement:
In order to protect the global data, i need to block the signal completely while i am accessing it inside the thread. So i need a way to implement it.
Problem:
I am not able to block the signals completely.
sigprocmask is not working. Although it blocks signal if main is the only thread running. But when multiple threads are running SIGALRM keeps on coming.
I have tested pthread_sigmask but that updates the signal mask for current thread only.
Adding code logic:
sig_atomic_t atm_var;
void signal_handler()
{
atm_var++;
}
void thread_func()
{
pthread_sigmask(UNBLOCK,...);
while(1)
{
/* some stuff */
pthread_sigmask(BLOCK,...);
/* critical section, can easily access or modify atm_var */
pthread_sigmask(UNBLOCK,...);
}
}
int main()
{
sigprocmask(BLOCK,...);
pthread_create(...,thread_func,...);
sigaction(SIGALRM,...);
setitimer(ITIMER_REAL,...);
while(1)
{
}
}
Adding one more point: How safe it is to modify a sig_atomic_t variable (that signal handler is modifying) in main or other threads?
OR
Will it be safe practice to not to block signal while i modify the sig_atomic_t variable inside main or other threads?
Your problem is that various signals can be directed at the whole process or a particular thread. When directed at the whole process then they will be delivered to any thread that doesn't have them blocked.
man (7) signal
A process-directed signal may be delivered to any one of the threads that does not currently have the signal blocked. If more than one of the threads has the signal unblocked, then the kernel chooses an arbitrary thread to which to deliver the signal.
Because the signal masks are inherited by each thread from whatever thread created them, a fairly standard technique is to block them in the creator (for simplicity let's say that is main) and then let each spawned thread unblock signals as appropriate.
A common variation on this is to block them in main, and keep them blocked in all spawned threads except one. That one thread unblocks the signals and all process directed signals get aimed at it to handle.
The above is probably what you want to do. You probably are properly blocking SIGALRM in the thread which is running the signal handler. Unfortunately that isn't going to prevent SIGALRM from being delivered to a second thread.
I'm a newbie in C. I want to create a program with two threads that will send signals (SIGUSR1 and SIGNUSR2) in a loop and four threads that will waiting for these signals and handle them.
I understood that sending the signal I need to do: kill(getpid,SIGUSR1); but howto I create four threads that will wait for the signal? the signal is registered to a specific function. How four threads will wait for the same signal?
Can I have other threads checking the type of signal also (without stopping the signal to reach the other threads)?
Thanks.
Update:
I'm trying to have four threads waiting for signals, when the two threads send the signals, the threads don't know which thread will catch the signal. I don't want to specify the thread id that will receive the signal.
When using pthread_kill() I need to specify the thread id (which I'm trying not to do).
Update: This answer is probably partly useless. You should use pthread_kill to send signals to a specific thread. I'll leave it around in case someone finds something in it, though.
On Linux, threads cannot be handled with kill, since kill will send the signal to any random thread that isn't blocking the signal.
Instead, you want the tgkill system call, which targets a specific thread. Which thread? You find out with the system call gettid.
Unfortunately, glibc doesn't provide wrappers for those two system calls. No problem, you can write those yourself:
#include <signal.h>
#include <sys/syscall.h>
#include <sys/types.h>
pid_t gettid()
{
return syscall(SYS_gettid);
}
int tgkill(int sig, pid_t pgid, pid_t tid)
{
return syscall(SYS_tkill, sig, pgid, tid);
}
The first argument of tgkill is the signal, as for kill. The second is the thread group id, which is the same as the process id of your process (obtainable with getpid). The last argument is the kernel thread id, which you obtain with gettid, and which also makes up the directories in /proc/<pid>/task/ on Linux.
Finally, you need to be able to wait for a signal to arrive. You do this by blocking the signal in the thread with pthread_sigmask and then using sigwaitinfo or sigtimedwait:
// block signal
sigset_t newset, oldset;
sigemptyset(&nweset);
sigaddset(&newset, SIGUSR1);
pthread_sigmask(SIG_BLOCK, &newset, &oldset);
// wait
sigwaitinfo(&newset, NULL);
// restore previous signal mask
pthread_sigmast(SIG_SETMASK, &oldset, NULL);
I really wouldn't recommend using SIGUSR signals for thread synchronization. If you want pthreads to wait on a signal, I'd look at the man pages for pthread_cond_signal
1-Sending unix signals is only possible to a processes, or it is also possible to send signals to threads?
2-Is it possible to send the tid of a thread to a kernel module? How?
3-In what way the kernel module can find the tid of a thread, to send a signal?
4-the thread will have a handler that will run on each signal. If each handler corresponds to a signal, are there any race conditions?
Can communicate a signal to all threads? What happens if all access the handler at a time?
Ad.1 From where do you want to send a signal? You can use kill() to send signal to process and pthread_kill() to send it to thread (but only from process which created thread).
Ad.3. While handling one signal, other pending signals will be queued, so there will be no race conditions. But you need to set non local variables used in handler to atomic (so when interrupt comes setting this variable will not be interrupted) and check which functions are handler safe.
About signals and threads - signal usually comes directly to process (only with pthread_kill you can send signal to thread from user space). If you have multithreaded process and none of thread has this signal blocked, then signal will come to random thread (the one which is running exactly when signal comes). If you block all threads but one, then signal will come to only this one thread.
I'm have a pthread function, which sleeps most of the time using usleep()
I would like to send a signal from the main process to the thread to interrupt the sleeping sometimes.
The problem is that I can't find any reference of which signal exactly to send using pthread_kill()
the usleep() man page, states that SIGALRM should not be used together with usleep()
Do I need to use a specific signal, it doesn't matter ?
The tools to synchronize between threads are not signals and usleep (or nanosleep) but combinations of pthread_mutex_t and pthread_cond_t. Just have your thread wait on a condition (this can be done with a timeout) and have your main thread send a "signal" on the condition variable.
usleep returns with EINTR on every signal that's delivered to a thread/process. You'll probably be best off using SIGUSR signals.
Also, usleep is now obsolete : consider using nanosleep instead. As an added bonus, you'll know how much sleep time was remaining at the time of the delivery of the signal.
I know how to send signals to child process in C using the kill(pid_t pid, int sig) function. What about sending signals to threads? is it possible?. If so, how to catch signals on the "child" thread. For example, if the main thread sends me a terminate signal, how can I in the other thread catch it.
With POSIX threads, you have the functions pthread_cond_wait and pthread_cond_signal.
int pthread_cond_wait(pthread_cond_t *restrict cond, pthread_mutex_t *restrict mutex)
int pthread_cond_signal(pthread_cond_t *cond)
The signaled thread should block on a pthread_cond_wait call until another thread sends a signal using pthread_cond_signal, with the same condition variable.
Considering the analogy with signals delivered to processes, this is a bit different because the signaled thread has already suspended its execution waiting for a signal, unlike a process that simply gets interrupted and goes on.
Signals are sent to a process as a whole. Each signal sent to the process is received by a single thread (on behalf of the whole program). There are per-thread signal masks which influence whether a particular thread is eligible to handle a particular signal.
So, you need a signal handler - possibly in just one thread. Note that there are limits on what you're supposed to do in a thread's signal handler, though. Be wary of stepping far outside the promises made by the standard (which are minimal).
However, the pthread_kill() function can be used to send signals to other threads as long as the current thread can identify (has access to the thread ID values (pthread_t) that identify) the threads that are still executing within the process. You might decide to relay the signal to the other threads using a different signal number from the one originally caught (so one thread receives the external signal, but many threads receive the internal signal). Or you might use another Pthread synchronization or communication primitive instead of signals.
Signals do not have thread affinity. They are handled completely asynchronously. When you specify a signal handler with signal(2) or sigaction(2), it's a global signal handler. When a signal is raised, the signal handler runs on top of the stack of whatever thread happens to be running at the time, and you can't control that.
It sounds like you want some other sort of interthread communication. The simplest way to do this is with a volatile shared variable:
volatile bool should_terminate = false;
void ChildThread()
{
while(!should_terminate)
{
// do stuff
}
}
void MainThread()
{
// To terminate child thread:
should_terminate = true;
}
If you need stronger concurrency control, look into mutexes, condition variables, and semaphores.
I'm not sure this is possible as it is platform and implementation dependant and I highly suggest you don't use signals to communicate between threads. Sometimes only a specific thread will receive signals and sometimes all threads receive signals.
Better thread communucation mechanisms exist like queues, semaphores, and locks.