【发布时间】:2017-11-26 03:27:07
【问题描述】:
我想在线程生命周期的前 100 秒忽略信号,我开发了这个解决方案但它不起作用,我缺少什么部分?
问题陈述: 编写一个有两个线程的程序——创建线程(线程 A)和创建线程(线程 B)。创建线程 B 后,线程 A 等待线程 B 终止,然后它自己终止。线程 B 只有在后面描述的特殊情况下才会终止。信号 SIGINT (ctrl C) 在线程 B 中被阻塞(即只有线程 A 处理 SIGINT)。每次,用户按下 ctrl C,线程 A 都会尝试取消线程 B。线程 B 会等待在其生命的前 100 秒内收到的任何取消请求。一旦线程 B 生命周期的前 100 秒结束,任何取消请求都会被兑现。此外,线程 B 在每 10 秒后以秒为单位打印其当前生命周期。
#include <pthread.h>
#include <stdio.h>
#include <errno.h>
#include <stdlib.h>
#include <unistd.h>
#include <signal.h>
#include <math.h>
#include <time.h>
#include <sys/time.h>
#define handle_error_en(en, msg) \
do { errno = en; perror(msg); exit(EXIT_FAILURE); } while (0)
void function_to_time(void);
static void *thread_func(void *arg)
{
struct sigaction act;
sigaction(SIGINT,NULL,&act);
act.sa_handler = SIG_IGN;
sigaction(SIGINT,&act,NULL);
sigset_t sigmask;
sigemptyset(&sigmask);
sigaddset(&sigmask, SIGALRM);
sigprocmask(SIG_BLOCK,&sigmask,NULL);
sigemptyset(&sigmask);
sigaddset(&sigmask,SIGALRM);
sigaddset(&sigmask,SIGINT);
alarm(100);
int sigintsReceived = 0;
int sigalrmsReceived = 0;
while( 1 == 1)
{
int recvdSig;
sigwait(&sigmask,&recvdSig);
if( recvdSig == SIGALRM )
{
if( sigalrmsReceived == 0 )
{
sigalrmsReceived++;
printf("\npthread_cancel is enabled\n");
sigset_t sigmask2;
sigemptyset(&sigmask2);
sigaddset(&sigmask2, SIGINT);
sigprocmask(SIG_BLOCK,&sigmask2,NULL);
sigaction(SIGINT,NULL,&act);
act.sa_handler = SIG_DFL;
sigaction(SIGINT,&act,NULL);
}
}
};
return 0;
}
int main(void)
{
sigset_t set;
pthread_t thr;
void *res;
int s;
s = pthread_create(&thr, NULL, &thread_func, (void *)&set);
if (s != 0)
handle_error_en(s, "pthread_create");
sigemptyset(&set);
sigaddset(&set, SIGINT);
pthread_sigmask(SIG_BLOCK, &set, NULL);
int recvdSig;
sigwait(&set,&recvdSig);
if( recvdSig == SIGINT )
{
printf("Signal received\n");
printf("main(): sending cancellation request\n");
s = pthread_cancel(thr);
if (s != 0)
handle_error_en(s, "pthread_cancel");
}
s = pthread_join(thr, &res);
if (s != 0)
handle_error_en(s, "pthread_join");
if (res == PTHREAD_CANCELED)
printf("main(): thread was canceled\n");
else
printf("main(): thread wasn't canceled (shouldn't happen!)\n");
exit(EXIT_SUCCESS);
}
【问题讨论】:
-
哪一部分不工作?
-
它没有忽略信号
-
@June 不忽略是什么意思? SIGINT 的默认行为是终止您的程序,如果没有发生,您的信号掩码有效。但是,您应该考虑到信号中断阻塞命令、唤醒进程(它们中断读取、睡眠或等待),这是无法避免的。看看你的返回值,是不是 EINTR (-4)?
-
此外,信号和信号处理程序适用于您的整个进程,而不是每个线程。任何线程都可以处理信号,但通常由主线程处理
-
@immortal 而
pthread_sigmask(3)呢?