在我的程序中,我使用 signalfd 来处理信号并将其与 poll 结合用于异步 IO。下面是我的代码:
#include <signal.h>
#include <stdio.h>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/syscall.h>
#include <sys/signalfd.h>
#include <unistd.h>
#include <string.h>
#include <pthread.h>
#include <sys/types.h>
#include <poll.h>
#include <assert.h>
#include <errno.h>
volatile sig_atomic_t cont = 1;
volatile sig_atomic_t usrcnt = 0;
volatile sig_atomic_t susrcnt = 0;
volatile sig_atomic_t wsig = 0;
volatile sig_atomic_t wtid = 0;
int GetCurrentThreadId()
{
return syscall(__NR_gettid);
}
void Segv1(int p1, siginfo_t * p2, void * p3)
{
//printf("SIGSEGV signal on illegal memory access handled by thread: %d\n", GetCurrentThreadId());
wtid = GetCurrentThreadId();
wsig = SIGSEGV;
_exit(SIGSEGV);
}
void Fpe1(int p1 , siginfo_t * p2, void * p3)
{
//printf is only for test.
//printf("FPE signal handled by thread: %d\n", GetCurrentThreadId());
wtid = GetCurrentThreadId();
wsig = SIGFPE;
_exit(SIGFPE);
}
void User1(int p1 , siginfo_t * p2, void * p3)
{
printf("User signal 1 handled by thread: %d\n", GetCurrentThreadId());
++susrcnt;
wtid = GetCurrentThreadId();
wsig = SIGUSR1;
}
void* ThreadFunc (void* d)
{
//Let us use signalfd.
int sfd;
sigset_t mask;
/* We will handle SIGTERM and SIGINT. */
sigemptyset (&mask);
sigaddset (&mask, SIGUSR1);
/* Create a file descriptor from which we will read the signals. */
sfd = signalfd (-1, &mask, 0);
if (sfd < 0) {
printf ("signalfd failed with %d\n", errno);
return NULL;
}
pthread_sigmask(SIG_BLOCK, &mask, NULL);
/* This is the main loop */
struct pollfd pfd[1];
int ret;
ssize_t bytes;
pfd[0].fd = sfd;
pfd[0].events = POLLIN | POLLERR | POLLHUP;
for (;;) {
ret = poll(pfd, 1, -1);
/* Bail on errors (for simplicity) */
assert(ret > 0);
assert(pfd[0].revents & POLLIN);
/* We have a valid signal, read the info from the fd */
struct signalfd_siginfo info;
bytes = read(sfd, &info, sizeof(info));
assert(bytes == sizeof(info));
unsigned sig = info.ssi_signo;
unsigned user = info.ssi_uid;
if (sig == SIGUSR1) {
++usrcnt;
printf ("Got SIGUSR1 by POLL in thread: %d: Handler count: %d, %d\n", GetCurrentThreadId(), susrcnt, usrcnt);
}
}
/* Close the file descriptor if we no longer need it. */
close (sfd);
return NULL;
}
int main()
{
const int numthreads = 1;
sigset_t sset;
struct sigaction act;
int sleepval = 15;
int pid;
int i;
int * a = 0;
//*a = 1;
int c=0;
//c = 0;
int b;
printf("My PID: %d\n", getpid());
printf("SIGSEGV: %d\nSIGFPE: %d\nSIGUSR1: %d\n", SIGSEGV, SIGFPE, SIGUSR1);
//Create a thread for signal
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);
sigemptyset(&sset);
sigaddset(&sset, SIGUSR1);
sigprocmask(SIG_UNBLOCK, &sset, NULL);
pthread_t tid[numthreads];
for(i=0;i<numthreads;++i)
pthread_create(&tid[i], NULL, ThreadFunc, NULL);
//Block the signal for main thread so that other thread handles the the signal.
pthread_sigmask(SIG_BLOCK, &sset, NULL);
sleep(numthreads/2);
//Raise user signal SIGUSR1.
//raise(SIGUSR1);
pid = fork();
if(pid) {
while(sleepval) {
sleepval = sleep(sleepval);
if(sleepval)
switch(wsig) {
case SIGSEGV:
printf("[Main] Segmenation fault in thread: %d\n", wtid);
exit(1);
break;
case SIGFPE:
printf("[Main] Floating point exception in thread: %d\n", wtid);
exit(1);
break;
case SIGUSR1:
printf("[Main] User 1 signal in thread: %d\n", wtid);
break;
default:
printf("[Main] Unhandled signal: %d in thread: %d\n", wsig, wtid);
break;
}
}
} else {
sleep(1); //To avoid race between signal handler and signal fd.
for(i=0;i<10;++i) {
//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);
//Problem is here. When the sleep(1) is commented out, it missed the signals.
kill(getppid(), SIGUSR1);
}
return 0;
}
return 0;
}
在程序中,进程生成一个线程,该线程创建 signalfd 并开始使用 poll。然后进程产生一个子进程,该子进程将 SIGUSR1 发送到父进程。当以 1s 的间隔发送信号时,它会处理所有信号。然而,当 sleep 被移除时,它错过了通知。
我想知道如果 signalfd 正在处理相同的信号,它是否也会丢弃信号通知。另外,信号处理程序和 signalfd 之间的优先顺序是什么?
最佳答案
如果一个进程有多个标准(即:非实时)信号挂起,操作系统可能会决定将多个相同类型的信号合并为一个。
来自 POSIX :
2.4.1 Signal Generation and Delivery
[...]
If a subsequent occurrence of a pending signal is generated, it is implementation-defined as to whether the signal is delivered or accepted more than once in circumstances other than those in which queuing is required.
默认情况下,标准信号不排队。使标准信号排队的唯一方法是使用 sigqueue() 发出它们.
关于c - signalfd() 遗漏信号,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/25717766/
我在ruby/rails中导入此CSV文件时遇到问题我得到的错误信息是这样的:Missingorstrayquoteinline1(CSV::MalformedCSVError)但我不确定发生了什么,因为我的CSV看起来非常好。以下是示例数据:"lesley_grades","lesley_id","last","first","active","site","cohort","section","sections_title","faculty","completed_term_cred","term","sec_start_date","sec_end_date","grade
目录一、inout在设计文件中的使用方法1.1、inout的第一种使用方法1.2、inout实现的第二种使用方法1.3、inout使用总结 二、inout在仿真测试中的使用方法一、inout在设计文件中的使用方法在FPGA的设计过程中,有时候会遇到双向信号(既能作为输出,也能作为输入的信号叫双向信号)。比如,IIC总线中的SDA信号就是一个双向信号,QSPIFlash的四线操作的时候四根信号线均为双向信号。在Verilog中用关键字inout定义双向信号,这里总结一下双向信号的处理方法。1.1、inout的第一种使用方法 实际上,双向信号的本质是由一个三态门组成的,三态门可以输出高电平,低电
我想从gtk3中的Widget发出自定义信号。在GTK2中,有一个名为signal_new的函数来创建一个新信号。您可以在此处查看示例:https://github.com/ruby-gnome2/ruby-gnome2/blob/ec373f87e672dbeeaa157f9148d18b34713bb90e/glib2/sample/type-register.rb在GTK3中,这个功能似乎不再可用。那么在ruby的GTK3中创建自定义信号的新方法是什么? 最佳答案 GTK3更改为使用define_signal方法而不是si
我想知道如何连接到带参数的信号(使用Rubyblock)。我知道如何连接到一个不带参数的:myCheckbox.connect(SIGNAL:clicked){doStuff}但是,这不起作用:myCheckbox.connect(SIGNAL:toggle){doStuff}它不起作用,因为切换槽采用参数voidQAbstractButton::toggled(boolchecked)。我怎样才能让它与参数一起工作?谢谢。 最佳答案 对您的问题的简短回答是,您必须使用slots方法声明要连接的插槽的方法签名:classMainGU
我有在服务器上运行的代码,在服务器硬关闭之前,发送了一个信号SIGTERM让我的代码知道它需要清理。我想在发生这种情况时运行代码并将信号发送回同一个程序,以便任何其他需要清理的代码都可以这样做。我不想捕获信号或改变信号行为,我只需要在我的程序的其余部分解释SIGTERM之前运行一些东西。目前我可以做类似的事情Signal.trap('TERM')doputs"Gracefulshutdown"exitend但如果同一个应用中的多段代码试图做同样的事情,它就不起作用了。例如:Signal.trap('TERM')doputs"Gracefulshutdown"exitendSignal.
在澄清了simplecov如何确定一条线是否已被测试执行之后。我有以下方法:defover?end_at其中end_at是对象的ActiveRecord属性。在以下规范中进行了练习:describeCalendarEntrydoit'candeterminethataneventhasended'do@entry.end_at=1.day.ago@entry.over?.shouldbe_trueendend在覆盖范围内运行规范后,它显示以下结果:我已经在Debug模式下运行了测试,并在此行上设置了一个断点,并确认规范确实符合它。这并不仅限于此方法中的这一行,包括使用ActiveRec
Heroku可能会出于各种原因向您的应用程序发送SIGTERM,因此我创建了一个处理程序来处理一些清理工作,以防发生这种情况。一些谷歌搜索没有给出任何关于如何在RSpec中测试它的答案或示例。这是基本代码:Signal.trap('TERM')docleanupenddefcleanupputs"doingsomecleanupstuff"...exitend当程序收到SIGTERM时,测试调用此清理方法的最佳方法是什么? 最佳答案 使用Process.kill'TERM',0将信号发送到RSpec并测试调用处理程序。确实,如果信号
也许你已经看到了这个......2012-03-07T15:36:25+00:00heroku[web.1]:StoppingprocesswithSIGTERM2012-03-07T15:36:36+00:00heroku[web.1]:StoppingprocesswithSIGKILL2012-03-07T15:36:36+00:00heroku[web.1]:ErrorR12(Exittimeout)->Processfailedtoexitwithin10secondsofSIGTERM2012-03-07T15:36:38+00:00heroku[web.1]:Proces
来自Process.kill的文档:Sendsthegivensignaltothespecifiedprocessid(s)ifpidispositive.IfpidiszerosignalissenttoallprocesseswhosegroupIDisequaltothegroupIDoftheprocess.signalmaybeanintegersignalnumberoraPOSIXsignalname(eitherwithorwithoutaSIGprefix).Ifsignalisnegative(orstartswithaminussign),killsproces
互联网这头“猪”真的掉下来了流量红利已经一去不复返了!3年前业界其实已经发出各种密集信号,在当时无论是BAT还是一些经济学家在3年前都已经预测过,互联网的流量模式已经衰竭,并且它将一去不复返。曾经处于互联网大潮的我们这一代人有喜有有悲也有感慨。还在4-5年前不少程序员会发觉在一个地方工作一年再跳一家公司,工资翻倍是至少的。其实这不是能力的表现这只不过是因此我们赶上了互联网流利红利、风投资本红利的“风口”而己。“赶上风口就连老母猪都能上树"用于形容当时的情形一点不为过。可是这个“风”这次是真的过去了,因此这头“猪”掉了下来,而且这次摔了还挺狠,直接给摔成了肉饼。业务模式、生态、环境的变革是时代的