Is there a way to change the signal mask of a thread from another thread?
I am supposed to write a multithreaded C application that doesn't use mutex, semaphores and condition variables, only signals.
So it would look like something like this:
The main Thread sends SIGUSR1 to its process and and one of the 2 threads (not including the main thread), will respond to the signal and block SIGUSR1 from the sigmask and sleep. Then the main thread sends SIGUSR1 again, the other thread will respond, block SIGUSR1 from its sigmask, unblock SIGUSR1 from the other threads sigmask, so it will respond to SIGUSR1 again.
So essentially whenever the main thread sends SIGUSR1 the two other threads swap between each other.
Can somebody help?
You are probably looking for pthread_sigqueue(3) called from the main thread, and sigwait(3) or sigtimedwait(2) in the child thread(s).
A thread can only modify its own signal mask (via pthread_sigmask()). If you want to modify another thread's signal mask, you will have to write code yourself to ask the other thread to do it.
Signals are being sent to the process here, so kill() or sigqueue() are the functions to use. The latter will avoid coalescing multiple signals together which may happen with kill().
Related
I want to wait for a pthread condition variable, but when I get a SIGUSR1 (or any other signal) I want to stop waiting and detect that it stopped waiting because of a signal, not because of a pthread_cond_signal or spurious wakeup. How can I do this?
A reliable way to handle signals in a pthreads program is to mask all the signals you wish to handle in every thread, and create a dedicated signal handling thread that loops around calling sigwaitinfo() (or sigtimedwait()).
The signal handling thread can then use ordinary mutex-protected shared variables and pthread_cond_signal() / pthread_cond_broadcast() wakeups to inform other threads about the signals received.
In your example, the dedicated signal handling thread could set a (mutex-protected) flag indicating that SIGUSR1 has been received, then signal the condition variable that your thread is waiting on. The waiting thread just needs to check the signal flags in addition to its other shared state in the loop around pthread_cond_wait().
My main thread has used pthread_create() to created some child threads. In the shut down handler(singal handler for SIGINT and SIGTERM) of the main thread, I want to use pthread_cancel to terminate all other threads. But I have malloc() in the those threads, how to free those memories?
You must refer http://man7.org/linux/man-pages/man3/pthread_kill.3.html
The pthread_kill instruction sends a signal sig to the specified thread. The signal to be sent is specified by sig and is either zero or one of the signals from the list of defined signals in the header file. If sig is zero, error checking is performed, but no signal is sent to the target thread.
pthread_kill, however, does not kill a thread. If that signal terminates the process, then the whole process ceases, and with it, any dynamically allocated memory by any thread in the process.
There is no way to kill a thread.
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.
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 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.