我正在尝试创建一个简单的shell,并添加了使用&在后台运行进程的function。 在我的主要方法中,我基本上有:
int main() { if (signal(SIGCHLD, handle) == SIG_ERR) perror("Cannot catch SIGCHLD"); pid_t child = fork(); if (child == 0) execvp(command, arguments); else { if (background == 1) { printf("1"); backgroundList(command, child); printf("2"); } else waitpid(child, NULL, 0); } }
对于我的经纪人,我有:
void handle(int s) { printf("a"); if (signal(SIGCHLD, handle) == SIG_ERR) perror("Cannot catch SIGCHLD"); pid_t pid; printf("b"); while((pid = waitpid(0, NULL, WNOHANG)) > 0) { printf("c"); rmBackgroundList(pid); printf("d"); } }
我可以让它在前台运行一个进程就好了。 运行“ls”将内容打印到屏幕上,然后打印“a”和“b”,因为它进入SIGCHLD处理程序,但它不会转到“c”,因为它已经等待了。
但是,在后台运行一些东西(“ls&”)将打印“1”和“2”,让父母返回提示,然后孩子将内容打印到屏幕,然后分段错误。 它不会打印处理程序中的任何字母。
我无法弄清楚为什么SIGCHLD对已经等待但却导致分段错误的孩子有好处,甚至从未进入处理器以处理未等待的进程。
您没有遵循信号处理程序的规则。 你不能使用printf()
或perror()
。 阅读有关信号处理程序中可安全操作的规则。
signal()
的行为也会发生变化,这取决于它是否是BSD或SysV样式的Unix。 Linux基于_BSD_SOURCE或_GNU_SOURCE的存在改变其在glibc中的行为,并且根据您是否调用gcc -ansi
或gcc -std=c99
或gcc -std=gnu99
你应该使用sigaction()
而不是signal()
。
以上就是c/c++开发分享SIGCHLD导致分段错误,而不是进入处理程序相关内容,想了解更多C/C++开发(异常处理)及C/C++游戏开发关注计算机技术网(www.ctvol.com)!)。
本文来自网络收集,不代表计算机技术网立场,如涉及侵权请联系管理员删除。
ctvol管理联系方式QQ:251552304
本文章地址:https://www.ctvol.com/c-cdevelopment/519112.html