- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
给定一个 Linux 系统,在 Haskell GHCi 8.8.3 中,我可以使用以下命令运行 Docker 命令:
System.Process> withCreateProcess (shell "docker run -it alpine sh -c \"echo hello\""){create_group=False} $ \_ _ _ pid -> waitForProcess pid
hello
ExitSuccess
create_group=True
时进程挂起。
create_group
的效果是打电话
set_pgid
与
0
in the child , 和
pid
in the parent .为什么这种变化会导致挂起?这是 Docker 中的错误吗? System.Process 中的错误?还是不幸但必要的互动?
最佳答案
这不是 Haskell 中的错误或 Docker 中的错误,而只是进程组的工作方式。考虑这个 C 程序:
#include <sys/types.h>
#include <stdio.h>
#include <unistd.h>
int main(void) {
if(setpgid(0, 0)) {
perror("setpgid");
return 1;
}
execlp("docker", "docker", "run", "-it", "alpine", "echo", "hello", (char*)NULL);
perror("execlp");
return 1;
}
./a.out
直接从您的交互式 shell 中,它会像您期望的那样打印“hello”。这并不奇怪,因为 shell 已经把它放在自己的进程组中,所以它的
setpgid
是一个空操作。如果您使用 fork 子程序运行它的中间程序运行它(
sh -c ./a.out
,
\time ./a.out
- 注意反斜杠,
strace ./a.out
等),那么
setpgid
将它放在一个新的进程组中,它会像在 Haskell 中一样挂起。
Macro: int SIGTTIN
A process cannot read from the user’s terminal while it is running as a background job. When any process in a background job tries to read from the terminal, all of the processes in the job are sent a
SIGTTIN
signal. The default action for this signal is to stop the process. For more information about how this interacts with the terminal driver, see Access to the Terminal.Macro: int SIGTTOU
This is similar to
SIGTTIN
, but is generated when a process in a background job attempts to write to the terminal or set its modes. Again, the default action is to stop the process.SIGTTOU
is only generated for an attempt to write to the terminal if theTOSTOP
output mode is set; see Output Modes.
docker run -it
有些东西,即使容器内的命令没有,Docker 也会尝试从 stdin 读取。由于您刚刚创建了一个新的进程组,并且您没有将其设置在前台,因此它被视为后台作业。因此,Docker 正在被
SIGTTIN
停止。 ,这会导致它看起来挂起。
signal
或 sigaction
使进程忽略 SIGTTIN
信号sigprocmask
阻止进程接收 SIGTTIN
信号tcsetpgrp(0, getpid())
使您的新进程组成为前台进程组(注意:这是最复杂的,因为它本身会导致 SIGTTOU
,因此无论如何您必须至少暂时忽略该信号)SIGTTIN
不会停止进程,从标准输入读取仍然会失败
EIO
,因此如果您确实要读取数据,那么您需要使用选项 4(并记住在 child 退出后将其设置回来)。
TOSTOP
设置(这不是默认设置),那么您必须重复修复
SIGTTOU
或者对于标准输出和标准错误(选项 4 除外,它根本不需要重复)。
关于docker - 启动 Docker 时使用 {create_group=True}/set_pgid 生成进程挂起,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/61856063/
给定一个 Linux 系统,在 Haskell GHCi 8.8.3 中,我可以使用以下命令运行 Docker 命令: System.Process> withCreateProcess (shell
我是一名优秀的程序员,十分优秀!