是否可以启动一个linux进程,获取PID,但在特定条件下稍后开始运行?
我正在考虑一种可以在程序开始时暂停程序的工具 例如,是否可以启动一个linux进程,获取PID,但在特定条件下稍后开始运行?,linux,Linux,我正在考虑一种可以在程序开始时暂停程序的工具 例如,my_bin立即开始运行 $ ./my_bin 用这个工具 $ magic_tool ./my_bin my_bin将启动。我可以得到PID。然后,我可以稍后开始实际运行。我刚刚在评论中测试了我的建议,它成功了!这是我的magic_tool.c中的代码: #包括 #包括 #包括 int main(int argc,char*argv[]) { pid_t pid; printf(“正在执行%s以包装%s。\n”,argv[0],argv[1
my_bin
立即开始运行
$ ./my_bin
用这个工具
$ magic_tool ./my_bin
my_bin
将启动。我可以得到PID
。然后,我可以稍后开始实际运行。我刚刚在评论中测试了我的建议,它成功了!这是我的magic_tool.c
中的代码:
#包括
#包括
#包括
int main(int argc,char*argv[])
{
pid_t pid;
printf(“正在执行%s以包装%s。\n”,argv[0],argv[1]);
pid=fork();
如果(pid==-1)
返回-1;
如果(pid==0){
升起(停止);
execl(argv[1],“”,NULL);
}否则{
printf(“PID==%d\n”,PID);
}
返回0;
}
我编写了另一个测试程序target.c
:
#包括
int main()
{
puts(“它工作!\n”);
返回0;
}
运行/magic\u tool./target
打印一个PID并返回shell。只有在运行kill-SIGCONT
was之后,它才能工作代码>打印。您可能希望将PID保存到其他地方,并在magic_tool
中执行一些检查,但我认为这仍然是一个很好的概念证明
编辑:
我在这方面做得比较多,但由于某些原因,它并不总是有效(参见下文的原因)。解决方案很简单-只需在magic\u tool.c
中更紧密地遵循适当的模式即可:
#包括
#包括
#包括
int main(int argc,char*argv[])
{
pid_t pid;
printf(“正在执行%s以包装%s。\n”,argv[0],argv[1]);
pid=fork();
如果(pid==-1)
返回-1;
如果(pid==0){
setsid();
pid=fork();
如果(pid==-1)
返回-1;
如果(pid==0){
升起(停止);
if(execl(argv[1],“”,NULL))
返回-1;
}
printf(“PID==%d\n”,PID);
}
返回0;
}
我发现了一个解释:
从shell启动根进程时,它是一个进程组组长,其子进程是该组的成员。当该领导终止时,进程组将成为孤立的。当系统检测到一个新孤立的进程组,其中的任何成员都被停止时,进程组的每个成员都会被发送一个SIGHUP,后跟一个SIGCONT
因此,当领导者终止时,您的一些后代进程仍然会停止,因此每个人都会收到一个SIGHUP,后面跟着一个SIGCONT,这实际上意味着他们会死于SIGHUP
确切地说,哪些后代仍然被阻止(甚至只是愉快地朝着exit()前进)是一场计时竞赛
答案还链接到包含更多细节的内容。这与@gst的想法非常相似,但完全在shell中完成,您可以生成一个子shell(这会分叉并创建一个新的pid),并在子shell收到SIGCONT信号并恢复时,让子shell自身发送SIGSTOP信号,子shellexec
用于指定程序(这将使用指定程序替换子shell,而不创建新的pid)。为了让主shell可以继续执行任务,子shell应该在后台运行,并带有&
简言之:
(kill -STOP $BASHPID && exec ./my_bin) &
subpid=$! # get the pid of above subshell
... do something else ...
kill -CONT $subpid # resume
另一个不受发送SIGCONT的主进程和子shell stop siging本身之间竞争条件影响的想法是使用文件描述符来实现等待:
exec {PIPEFD}<> <(:) # set PIPEFD to the file descriptor of an anonymous pipe
(read -u $PIPEFD && exec ./my_bin) &
subpid=$! # get the pid of above subshell
... do something else ...
echo >&$PIPEFD # resume
exec{PIPEFD}&$PIPEFD#resume
你能提供更多关于用途/用例的信息吗?相关:@igr Just curiosityStart a process,fork
,将孩子的pid保存在某个地方,让孩子在调用execve
之前将SIGSTOP
发送给自己,然后用我的bin
调用execve
,家长退出,稍后用SIGCONT
继续给孩子。我错过什么了吗?(真正的问题,不确定这是否有效)我很好奇为什么你认为这会有用;为什么需要这样一个工具?