gpt4 book ai didi

c - 辅助线程中的信号处理

转载 作者:塔克拉玛干 更新时间:2023-11-03 01:58:13 24 4
gpt4 key购买 nike

我正在编写一个程序来演示辅助线程中的信号处理。在我的程序中,主线程生成 10 个线程,每个线程调用 sigwait 来等待信号。但就我而言,处理信号的是主线程。代码如下:

#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上有没有拾取线程处理信号的规则?我应该怎么做才能在辅助线程中处理信号?

在上面的程序中,我无法在辅助线程中处理信号。有什么问题吗?

最佳答案

我建议您应该在主线程中 SIG_BLOCK 需要的信号(现在已注释掉)并在其他线程中 SIG_UNBLOCK 它们(现在 SIG_BLOCK)。或者你可以生成你的线程,然后在主线程中生成 SIG_BLOCK,因为生成的线程从父线程获得它们的 sigmask。而且sigsuspend的参数不是你要唤醒的信号,反之亦然。

关于c - 辅助线程中的信号处理,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/25659579/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com