- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
我正在研究信号:特别是 SIGSTOP
和 SIGCONT
。这是我写的一个测试程序。这个想法是创建一个 N + 1 的链进程(包括主进程)。每个人都必须等待它的 child 停止,然后停止本身。当后者有停止了。
为此,f
函数递归地创建流程链。每一个该进程在 SIGCHLD
信号上使用 sigsuspend,除了最后一个直接停下自己的 child 。当它的 child 停止时,一个进程将接收到 SIGCHLD
信号,然后它可以在轮到它时停止。什么时候主进程收到 SIGCHLD
信号,这意味着所有的进程处于停止状态,因此它向其发送 SIGCONT
信号 child 。每个进程发送 SIGCONT
给自己的子进程然后退出,分开来自刚刚退出的最后一个 child 。
我试图说清楚:删除了返回码测试并写了一些评论。
当执行程序时,一切似乎都很好,但 SIGCONT
链。一些进程被唤醒,但不是全部。看着运行程序(例如使用 ps)一切似乎都很好:否阻塞的进程。我真的不明白这有什么问题程序。欢迎任何帮助或提示。
这是一个示例跟踪。如您所见,“ fork 链”运行良好,进程因 SIGCHLD
而暂停。然后最后一个 child 产卵并停止。这会在父级上创建一个“SIGCHLD
链”,因为每个进程都会自行停止。当主进程收到 SIGCHLD
的通知时,它会向其子进程发送 SIGCONT
,该子进程被唤醒并依次向其自己的子进程发送 SIGCONT
等等。你会注意到这条链是不完整的:
$ ./bin/trycont
n pid log
0 6257 "suspending on SIGCHLD"
1 6258 "suspending on SIGCHLD"
2 6259 "suspending on SIGCHLD"
3 6260 "suspending on SIGCHLD"
4 6261 "suspending on SIGCHLD"
5 6262 "last child - stopping"
4 6261 "got SIGCHLD"
4 6261 "stopping"
3 6260 "got SIGCHLD"
3 6260 "stopping"
2 6259 "got SIGCHLD"
2 6259 "stopping"
1 6258 "got SIGCHLD"
1 6258 "stopping"
0 6257 "got SIGCHLD"
0 6257 "sending SIGCONT to 6258"
1 6258 "awakened - sending SIGCONT to 6259"
2 6259 "awakened - sending SIGCONT to 6260"
# <- not the expected trace
这是程序:src/trycont.c
#include <stdlib.h>
#include <stdio.h>
#include <unistd.h>
#include <signal.h>
/* number of created processes with fork
*/
#define N 5
#define printHeader() printf("n\tpid\tlog\n");
#define printMsg(i, p, str, ...) printf("%d\t%d\t" #str "\n", i, p, ##__VA_ARGS__)
void f(int n);
void handler(int sig);
sigset_t set;
struct sigaction action;
int main(int argc, char *argv[])
{
/* mask SIGCHLD
*/
sigemptyset(&set);
sigaddset(&set, SIGCHLD);
sigprocmask(SIG_SETMASK, &set, NULL);
/* handler will be called when SIGCHLD is sent to the process
* during the handler, SIGCHLD will be masked (sa_mask)
*/
action.sa_mask = set;
action.sa_handler = handler;
action.sa_flags = 0;
/* SIGCHLD will trigger action
*/
sigaction(SIGCHLD, &action, NULL);
/* start
*/
printHeader();
f(N);
exit(EXIT_SUCCESS);
}
void f(int n)
{
pid_t p, pc;
int myIndex;
myIndex = N - n;
p = getpid();
if (n == 0)
{
/* last child
*/
printMsg(myIndex, p, "last child - stopping");
kill(p, SIGSTOP);
printMsg(myIndex, p, "END REACHED");
exit(EXIT_SUCCESS);
}
pc = fork();
if (pc == 0)
{
/* recursion
*/
f(n - 1);
/* never reached
* because of exit
*/
}
/* father
*/
/* suspending on SIGCHLD
* need to unmask the signal
* and suspend
*/
printMsg(myIndex, p, "suspending on SIGCHLD");
sigfillset(&set);
sigdelset(&set, SIGCHLD);
sigsuspend(&set);
printMsg(myIndex, p, "got SIGCHLD");
if (n < N)
{
/* child process
* but not last
*/
printMsg(myIndex, p, "stopping");
kill(p, SIGSTOP);
printMsg(myIndex, p, "awakened - sending SIGCONT to %d", pc);
kill(pc, SIGCONT);
}
else
{
/* root process
*/
printMsg(myIndex, p, "sending SIGCONT to %d", pc);
kill(pc, SIGCONT);
}
exit(EXIT_SUCCESS);
}
void handler(int sig)
{
switch (sig)
{
case SIGCHLD:
/* when the process received SIGCHLD
* we can ignore upcoming SIGCHLD
*/
action.sa_handler = SIG_IGN;
sigaction(SIGCHLD, &action, NULL);
break;
default:
break;
}
}
如果您需要,这里有一个 Makefile:
CC=gcc
DEFINES=-D_POSIX_C_SOURCE
STD=-std=c11 -Wall -Werror
OPTS=-O2
CFLAGS=$(STD) $(DEFINES) $(OPTS) -g
LDFLAGS=
SRC=src
OBJ=obj
BIN=bin
DIRS=$(BIN) $(OBJ)
.PHONY: mkdirs clean distclean
all: mkdirs $(BIN)/trycont
$(BIN)/%: $(OBJ)/%.o
$(CC) $(CFLAGS) $(LDFLAGS) -o $@ $<
$(OBJ)/%.o: $(SRC)/%.c
$(CC) $(CFLAGS) -c -o $@ $<
mkdirs:
- mkdir $(DIRS)
clean:
rm -vf -- $(OBJ)/*.o
distclean: clean
rm -vfr -- $(DIRS)
最佳答案
当第一个进程终止时,您的某些(全部?)后代进程正在死于系统生成的 SIGHUP。
这是 expected POSIX behavior在某些情况下。
当您从 shell 启动根进程时,它是一个进程组组长,它的后代是该组的成员。当该领导者终止时,进程组将孤立。当系统检测到任何成员停止的新孤立进程组时,进程组的每个成员都会收到一个 SIGHUP,然后是一个 SIGCONT。
因此,当领导者终止时,您的一些后代进程仍会停止,因此每个人都会收到一个 SIGHUP,然后是一个 SIGCONT,这实际上意味着他们死于 SIGHUP。
究竟哪些后代仍然停止(或者甚至只是愉快地向 exit()
前进)是一场计时赛跑。在我的系统上,领导者很快终止,以至于没有一个后代能够打印任何东西。
关于c - SIGSTOP/SIGCONT POSIX 行为,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/40029116/
是否有详细说明从一个 POSIX 版本更改为另一个版本的文档?我正在寻找一些东西,在表格 View 中,详细说明从 2004 年到 2008 年的变化 最佳答案 有点。这是Rationale ,每卷一
根据POSIX FAQ ,该标准已于 2013 年由 IEEE 修订和批准。 与 2008 年的先前标准相比有何变化? 最佳答案 根据 online edition 中的摘要, POSIX.1-2
我正在开发一个简单的并行应用程序,我想在其中使用单个进程来维护有关一系列工作进程的状态信息。设置一个 POSIX 消息队列似乎相对容易,其中所有工蜂都可以向状态维护者发送定期更新。我的问题? POSI
计划使用 posix 信号量来同步 2 个进程。不太确定使用哪个 - 命名或未命名。 各自的优缺点是什么?我如何决定使用哪个?在哪些情况下,一种优于另一种? 谢谢。 最佳答案 如果这两个进程不相关,则
嵌套参数替换在 Zsh 中有效: $ param=abc # nested remove prefix ${...#a} and remove suffix ${...%c} => $ printf
更新:整个问题出在一条错误线上,这是我的 C++ 代码中的语法错误。 在 Linux 上我发现 #define _NSIG 64 在 asm-generic/signal.h ,
我在网上遇到了两个 POSIX 文档。 http://pubs.opengroup.org/onlinepubs/009695399/ (IEEE 标准 1003.1,2004 年版) Abstrac
我正在开发一个简单的软件来检查我是否能够使用我研究过的 POSIX 定时器和信号进行编程。 我正在尝试做一个简单的程序来启动计时器并在一定的纳秒内发出信号 下面的程序运行得不好,所以我写了一些关于我的
如果我有一个通过 shell 运行的应用程序,是否有 POSIX 文档说 --help需要支持吗?我会这么认为,因为这似乎是最流行的终端应用程序(GNU 工具等)中的标准做法。 我很好奇我是否可以使用
自适应 AUTOSAR 基于什么 POSIX PSE51? 在学习自适应 AUTOSAR 时,我发现“自适应 AUTOSAR 基于 POSIX PSE51”。 但是,我不明白什么是 POSIX PSE
GNU bash manual说到shell参数有以下一段话: The command builtin does not prevent builtins that take assignment s
我应该在我的嵌入式 Linux 环境中使用 System V 消息队列还是 Posix 消息队列?项目中常用什么? 最佳答案 两者都有相同的基本工具——信号量、共享内存和消息队列。它们为这些工具提供了
用 tsearch 填充了 POSIX 二叉树后,如何清理整棵树? GCC 提供了 tdestroy 作为扩展,但是如果你想使用 POSIX-only 函数,你该怎么做呢? 我当前的实现使用 twal
来自 C++ 应用程序。为 AIX、HP-UX、Linux、OSX 和 Solaris 编译是否有一种简单的方法来确定应用程序是否可用。在系统启动后 5 分钟内运行? 在 Windows 上我可以这样
System V IPC 和 POSIX IPC 之间有什么区别? 为什么我们有两个标准? 如何决定使用哪些 IPC 函数? 最佳答案 两者都有相同的基本工具——信号量、共享内存和消息队列。它们提供的
根据this ,POSIX 库不包含 getopt.h。但是,我在 unistd.h 中找到了这个: #ifdef __USE_POSIX2 /* Get definitions and proto
我正在尝试使用 POSIX 共享内存和 POSIX 信号量构建客户端服务器应用程序。我是否必须将信号量放在共享内存段内,或者信号量是否可以只是全局变量?我希望遵守 POSIX 约定。 最佳答案 不,信
尝试读取 Rust fn 中任意用户的主目录,并使用 posix::pwd crate。 不幸的是,我找不到任何使用 FFI 的好例子,并且一直在处理关于指针和类型可变性的各种类型错误。 我的(非编译
我阅读了一个信号的手册页使用 man 7 signal我看到两种类型的信号。所以,我有一个问题, Linux 中的POSIX 可靠信号 和POSIX 实时信号 有什么区别? 最佳答案 如今,将这些表述
据我所知,ucontext 提供了比 setjmp 更好的东西。但它已被弃用,现在已从 POSIX 规范中删除。那么它为什么会出现,又为什么会被移除? 最佳答案 makecontext的签名来自 uc
我是一名优秀的程序员,十分优秀!