Tag: 信号

忽略子进程中的SIGINT信号

我正在编写一个简单的程序,其中父和子进程可以打印到文件中。 我已经设法使用用户定义的信号来做到这一点。 现在我想处理SIGINT信号。 一旦收到ctrl-c ,父母必须向孩子发送终止信号,孩子应该终止,最后父母应该终止。 我的问题是,为了使这项工作正常,我必须只从父母那里获取SIGINT信号,而从儿童那里获取IGNORE。 这样对吗? 如果是的话有任何暗示吗?

等待信号,然后继续执行

我正在尝试制作一个暂停执行的程序, 直到信号到达 。 然后,在信号到达后,我只想让我的代码从原来的位置继续执行 。 我不希望它执行函数处理程序或任何其他。 有一个简单的方法吗? 我已经挣扎了一个星期左右,在这里和那里阅读,并没有设法得到一个完整的操作代码。 特别是,我希望主程序创建一个等待某个特定事件发生的线程 (例如,用户已经向stdin输入了一些数据)。 与此同时,主程序正在做一些事情,但在某些时候它会暂停执行,直到收到信号。 信号可能来自线程,因为它已检测到事件,或者可能是由于超时,因为我不希望它等待。 我已经制作了一些代码,但它没有按预期工作…… /* * This code SHOULD start a thread that gets messages from stdin. * If the message is a “quit”, the thread exits. Otherwise it raises * a signal that should be caught by the main program. * The main program simply […]

libsigsegv并响应堆栈溢出

我们正在尝试测试学生代码,并且为了自动化该过程,我们想要检测学生的代码是否溢出堆栈。 我使用libsigsegv库及其相应的stackoverflow_install_handler获得了一些成功。 它的工作非常出色,直到学生的代码两次打击堆栈。 例如,这里是一些示例输出: [# ~]$ ledit ./interpreter -> (use solution) -> (fun 1 2) *** Stack overflow detected *** -> (fun 1 2) Signal -10 [# ~] 初始“ *检测到堆栈溢出* ”是理想的输出。 在第二次吹掉堆栈之后,我得到的只是一个无用的“Signal -10”,程序停止执行。 我想再次看到堆栈溢出检测到的消息,让代码继续执行。 在我的堆栈溢出处理程序中,我只是将溢出检测消息打印到stderr并且长时间跳回到解释器中的“等待输入状态”。 谢谢你的帮助! 编辑 根据下面的caf的建议,我们添加了对sigsegv_leave_handler()的调用,如下所示: static void continuation(void *arg1, void *arg2, void *arg3) { (void)(arg1); (void)(arg2); (void)(arg3); siglongjmp(errorjmp, 1); } static void […]

便携式捕获信号并向用户报告问题的方法

如果由于某些奇迹在我们的程序中发生了段错误,我想要捕获SIGSEGV并让用户(可能是GUI客户端)知道一个返回码,发生了严重的问题。 同时我想在命令行上显示信息以显示捕获的信号。 今天我们的信号处理程序如下所示: void catchSignal (int reason) { std :: cerr << "Caught a signal: " << reason << std::endl; exit (1); } 我可以听到上面的恐怖尖叫,正如我从这个post中读到的那样,从信号处理程序调用非重入函数是邪恶的。 是否有便携式方式处理信号并向用户提供信息? 编辑:或至少在POSIX框架内可移植?

如何在C中正确等待我自己的shell中的前台/后台进程?

在上一个问题中,我发布了大部分自己的shell代码。 我的下一步是实现前台和后台进程执行并正确等待它们终止,这样它们就不会像“僵尸”那样停留。 在添加在后台运行它们的可能性之前,所有进程都在前台运行。 为此,我在使用execvp()执行任何进程后简单地调用wait(NULL)。 现在,我检查’&’字符作为最后一个参数,如果它在那里,通过不调用wait(NULL)在后台运行该进程,并且进程可以在后台运行愉快我将返回到我的shell。 这一切都正常(我认为),现在的问题是,我还需要以某种方式调用wait()(或waitpid()?),以便后台进程不会保持“僵尸”。 这是我的问题,我不知道该怎么做…… 我相信我必须处理SIGCHLD并在那里做一些事情,但是我还没有完全理解何时发送SIGCHLD信号,因为我还试图将wait(NULL)添加到childSignalHandler()但是它不起作用因为我一旦在后台执行了一个进程,调用了childSignalHandler()函数,因此等待(NULL),这意味着在“后台”进程完成之前我无法对我的shell做任何事情。 由于信号处理程序中的等待,它不再在后台运行。 我在这一切中缺少什么? 最后一件事,这个练习的一部分我还需要打印进程状态的变化,比如进程终止。 因此,对此的任何见解也非常感激。 这是我目前的完整代码: #include #include #include #include #include #include #include #include “data.h” // Boolean typedef and true/false macros void childSignalHandler(int signum) { // } int main(int argc, char **argv) { char bBuffer[BUFSIZ], *pArgs[10], *aPtr = NULL, *sPtr; bool background; ssize_t rBytes; int aCount; pid_t pid; […]

使用sigaction(),c / cpp

我正在做一些关于sigaction()的阅读(来自我的课程笔记)并且我不确定我理解这个文本: 仅在信号处理程序的持续时间内计算并安装信号掩码。 默认情况下,信号“sig”也会在信号发生时被阻止。 使用sigaction为特定信号安装操作后,它将保持安装状态,直到明确请求另一个操作。 这是否意味着在从信号处理程序返回后恢复默认信号掩码? 另外,使用后我是否必须重新安装处理程序,就像我使用signal()一样 还有,这段代码: #include #include #include #include void termination_handler(int signum) { exit(7); } int main (void) { struct sigaction new_action,old_action; new_action.sa_handler = termination_handler; sigemptyset(&new_action.sa_mask); sigaddset(&new_action.sa_mask, SIGTERM); new_action.sa_flags = 0; sigaction(SIGINT, NULL, &old_action); if (old_action.sa_handler != SIG_IGN) { sigaction(SIGINT,&new_action,NULL); } sleep(10); return 0; } 那么 – SIGTERM究竟将如何处理? 我可以看到已安装的处理程序是终止)handler(),但是SIGTERM被添加到信号掩码中而没有使用sigprocmask()。 这是什么意思? 谢谢! Ps最后一个问题:为什么main()中的if语句?

信号处理和sigemptyset()

任何人都可以用一种非常简单的方式来解释sigemptyset()的作用吗? 为什么有用? 我读了一堆定义,但我只是不明白。 从我收集的内容中,它跟踪用于阻止目的的信号? 我不太清楚我明白为什么那会有用。 是这样我们不能递归地得到那个特定的信号吗? 使用sigemptyset()的基本示例: #include #include #include int main(){ struct sigaction act; sigemptyset(&act.sa_mask); act.sa_handler=function_name; act.sa_flags=0; sigaction(SIGINT, &act, 0); }

fork(应该是)在线程程序中对信号处理程序是否安全?

我真的不确定POSIX在存在线程和信号时对fork的安全性的要求。 fork被列为异步信号安全函数之一,但是如果库代码有可能注册了非异步信号安全的pthread_atfork处理程序,这会否定fork的安全性吗? 答案取决于运行信号处理程序的线程是否正在使用atfork处理程序所需的资源? 或者换句话说,如果atfork处理程序使用同步资源(互斥体等),但是从一个永远不会访问这些资源的线程中执行的信号处理程序调用fork ,程序是否符合要求? 在这个问题的基础上,如果使用pthread_atfork建议的习语在系统库内部实现“线程安全”分叉(获取prefork处理程序中的所有锁并释放父和子postfork处理程序中的所有锁),那么就是fork在线程程序中使用信号处理程序是否安全? 处理信号的线程是否可能在调用malloc或fopen / fclose并持有全局锁的过程中,导致fork期间出现死锁? 最后,即使fork在信号处理程序中是安全的,在信号处理程序中fork然后从信号处理程序返回是安全的,或者在信号处理程序中调用fork总是需要后续调用_exit或其中一个exec信号处理程序返回之前的函数族?

在sigprocmask()中设置和设置

我还没有完全理解,如何使用sigprocmask() 。 特别是, set和oldset及其语法如何工作以及如何使用它们。 int sigprocmask(int how, const sigset_t *set, sigset_t *oldset); 请解释一个例子,阻止,说SIGUSR1几秒钟,然后解锁并处理它。

有没有办法让我的程序使用更少的代码?

我为学校作业编写了以下代码 – 它编译并打印所有正确的消息。 但仅仅是出于我自己的好奇心,我想知道我的代码是否可以缩短并且仍然有效。 我试过“信号”而不是“sigaction”,但我听说“sigaction”比“信号”更受欢迎。 此外,此分配需要3个处理程序。 有人可以看看并给我一些提示吗? 谢谢! #define _POSIX_SOURCE #define _BSD_SOURCE #include #include #include #include #include #include #include static void sigHandler_sigusr1(int sig) { printf(“Caught SIGUSR1\n”); //sig contains the signal number that was received } static void sigHandler_sigusr2(int sig) { printf(“Caught SIGUSR2\n”); } static void sigHandler_sigint(int sig) { printf(“Caught SIGINT, Existing\n”); exit(EXIT_SUCCESS); } int main(int […]