可以$!在并行运行的脚本中使用时会导致竞争条件?


8

假设我有多个并行运行的bash脚本,其代码如下所示:

#!/bin/bash

tail -f /dev/null &
echo "pid is "$!

可以$!确保为我提供该脚本中最新后台任务的PID ,还是全局上最新后台任务的PID ?我很好奇,如果它返回的PID来自另一个脚本中启动的进程,则依靠此功能是否会导致争用情况。

Answers:


16

$!确保为您提供Shell执行该tail命令的过程的pid 。外壳程序是单线程的,每个外壳程序都有自己的变量集,位于各自的进程中。$!一个外壳程序的方法不可能泄漏到另一个外壳程序中,就像在一个外壳程序中分配一个外壳程序变量不会影响另一个外壳程序中同名的变量一样(如果我们不考虑外壳程序的通用变量fish) 。

现在,它tail -f /dev/null是一个无限期运行的命令,但是对于短命的命令,请注意,由于可能的进程ID数量有限,因此不可避免地会重复使用进程ID。

在:

true &
pid=$!

$pid将包含运行shell的进程的ID true,但是到您使用$pid该ID时,该pid可能已死,并且可能引用了另一个进程。


3
是的,我知道您的第二点,并且,如果您想成为可靠的后台流程管理器,则需要使用一种语言,以确保您知道子进程已退出并且其PID已返回到池中的确切时间。 ,外壳脚本显然无法执行,因为它们可以积极地获取子进程。感谢您的明确解释。
philraj

5
@philraj,在zsh中,您可以在SIGCHLD上安装处理程序,这些处理程序在异步作业终止时进行处理,并用于$jobstate/$jobtext检查那里的进程状态。并非没有种族,因为执行陷阱时孩子已经被收割,但这意味着非常短的种族窗口,其中pid不太可能已经被重用。
斯特凡Chazelas
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.