【发布时间】:2014-10-28 20:31:01
【问题描述】:
我正在编写一个程序来演示辅助线程中的信号处理。在我的程序中,主线程产生 10 个线程,每个线程调用sigwait 等待信号。但就我而言,处理signa的是主线程。代码如下:
#include <signal.h>
#include <stdio.h>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/syscall.h>
#include <unistd.h>
#include <string.h>
#include <pthread.h>
#include <sys/types.h>
#include <errno.h>
volatile sig_atomic_t cont = 1;
volatile sig_atomic_t wsig = 0;
volatile sig_atomic_t wtid = 0;
int GetCurrentThreadId()
{
return syscall(__NR_gettid);
}
void Segv1(int, siginfo_t *, void *)
{
//printf("SIGSEGV signal on illegal memory access handled by thread: %d\n", GetCurrentThreadId());
wtid = GetCurrentThreadId();
wsig = SIGSEGV;
_exit(SIGSEGV);
}
void Fpe1(int , siginfo_t *, void *)
{
wtid = GetCurrentThreadId();
wsig = SIGFPE;
_exit(SIGFPE);
}
void User1(int, siginfo_t *, void *)
{
wtid = GetCurrentThreadId();
wsig = SIGUSR1;
}
void* ThreadFunc (void*)
{
sigset_t sigs;
sigemptyset(&sigs);
sigaddset(&sigs, SIGUSR1);
sigaddset(&sigs, SIGSEGV);
sigaddset(&sigs, SIGFPE);
pthread_sigmask(SIG_BLOCK, &sigs, NULL);
//printf("Thread: %d starts\n", GetCurrentThreadId());
while(cont) {
//printf("Thread: %d enters into loop\n", GetCurrentThreadId());
//int s = sigwaitinfo(&sigs, NULL);
//int sig;
//int s = sigwait(&sigs, &sig);
//printf("A signal\n");
/*if(s==0) {
sigaddset(&sigs, sig);
printf("Signal %d handled from thread: %d\n", sig, GetCurrentThreadId());
if(sig==SIGFPE||sig==SIGSEGV)
return NULL;
} else {
printf("sigwaitinfo failed with %d\n", s);
break;
}*/
int s = sigsuspend(&sigs);
switch(wsig) {
case SIGSEGV:
printf("Segmenation fault in thread: %d Current thread id: %d\n", wtid, GetCurrentThreadId());
exit(1);
break;
case SIGFPE:
printf("Floating point exception in thread: %d Current thread id: %d\n", wtid, GetCurrentThreadId());
exit(1);
break;
case SIGUSR1:
printf("User 1 signal in thread: %d Current thread id: %d\n", wtid, GetCurrentThreadId());
break;
default:
printf("Unhandled signal: %d in thread: %d Current thread id: %d\n", wsig, wtid, GetCurrentThreadId());
break;
}
}
printf("Thread: %d ends\n", GetCurrentThreadId());
return NULL;
}
int main()
{
printf("My PID: %d\n", getpid());
printf("SIGSEGV: %d\nSIGFPE: %d\nSIGUSR1: %d\n", SIGSEGV, SIGFPE, SIGUSR1);
//Create a thread for signal
struct sigaction act;
memset(&act, 0, sizeof act);
act.sa_sigaction = User1;
act.sa_flags = SA_SIGINFO;
//Set Handler for SIGUSR1 signal.
if(sigaction(SIGUSR1, &act, NULL)<0) {
fprintf(stderr, "sigaction failed\n");
return 1;
}
//Set handler for SIGSEGV signal.
act.sa_sigaction = Segv1;
sigaction(SIGSEGV, &act, NULL);
//Set handler for SIGFPE (floating point exception) signal.
act.sa_sigaction = Fpe1;
sigaction(SIGFPE, &act, NULL);
sigset_t sset;
sigemptyset(&sset);
sigaddset(&sset, SIGUSR1);
sigaddset(&sset, SIGSEGV);
sigaddset(&sset, SIGFPE);
//pthread_sigmask(SIG_BLOCK, &sset, NULL);
const int numthreads = 10;
pthread_t tid[numthreads];
for(int i=0;i<numthreads;++i)
pthread_create(&tid[i], NULL, ThreadFunc, NULL);
sleep(numthreads/2);
int sleepval = 15;
int pid = fork();
if(pid) {
while(sleepval) {
sleepval = sleep(sleepval);
//It might get interrupted with signal.
switch(wsig) {
case SIGSEGV:
printf("Segmenation fault in thread: %d\n", wtid);
exit(1);
break;
case SIGFPE:
printf("Floating point exception in thread: %d\n", wtid);
exit(1);
break;
case SIGUSR1:
printf("User 1 signal in thread: %d\n", wtid);
break;
default:
printf("Unhandled signal: %d in thread: %d\n", wsig, wtid);
break;
}
}
} else {
for(int i=0;i<10;++i) {
kill(getppid(), SIGUSR1);
//If sleep is not used, signal SIGUSR1 will be handled one time in parent
//as other signals will be ignored while SIGUSR1 is being handled.
sleep(1);
}
return 0;
}
int * a = 0;
//*a = 1;
int c=0;
//c = 0;
int b = 1/c; //send SIGFPE signal.
return 0;
}
在 Linux 和 Mac OS X 上选择线程进行信号处理是否有任何规则?我应该怎么做才能让信号在辅助线程中得到处理?
在上述程序中,我无法在辅助线程中处理信号。它有什么问题?
【问题讨论】:
-
首先在上面的链接中得到了回答。但我面临第二部分的问题(在辅助线程中处理信号)。
-
第二个也有答案。
-
仍然,我无法解决第二部分。你能提到它的答案吗?