$できます!並列実行されているスクリプトで使用すると競合状態が発生しますか?


8

次のようなコードで、並行して実行される複数のbashスクリプトがあるとします。

#!/bin/bash

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

そのスクリプトの$!最新のバックグラウンドタスクのPIDを取得することが保証されていますか、それともグローバルな最新のバックグラウンドタスクですか?この機能に依存すると、PIDが別のスクリプトで開始されたプロセスからのPIDである場合に競合状態が発生する可能性があるかどうか、私は興味があります。

回答:


16

$!シェルがそのtailコマンドを実行したプロセスのPIDを提供することが保証されています。シェルはシングルスレッドであり、各シェルは独自の変数セットを持つ独自のプロセス内に存在します。方法はありません$!1つのシェルのをしようとしている漏れるだけで(私たちはさておき設定されている場合、別のシェルで同じ名前の変数に影響を与えるつもりはないされて1つのシェルでシェル変数を割り当てるように、別のシェルに普遍変数fishシェル) 。

現在、tail -f /dev/nullは無期限に実行されるコマンドですが、有効期間が短いコマンドの場合、可能なプロセスIDの数が限られているため、プロセスIDは必然的に再利用されることに注意してください。

に:

true &
pid=$!

これ$pidには、シェルが実行されたプロセスのIDが含まれますが、それtrueを使用するまでに$pid、そのPIDは無効になり、別のプロセスを参照している可能性があります。


3
はい、私はあなたの2番目の点を認識しており、信頼できるバックグラウンドプロセスマネージャーを作成する場合は、子プロセスが終了し、そのPIDがプールに返された正確な瞬間を確実に理解できる言語を使用する必要があることを知っています。どうやら、シェルスクリプトは子プロセスを積極的に取得するため、シェルスクリプトではできません。分かりやすい説明ありがとうございます。
philraj

5
@ philraj、zshでは、非同期ジョブの終了時に処理されるハンドラーをSIGCHLDにインストールして、$jobstate/$jobtextそこでプロセスのステータスを検査するために使用できます。トラップが実行されたときに子がすでに刈り取られているため、人種がないわけではありませんが、これは、pidがすでに再利用される可能性が非常に低い非常に短い人種ウィンドウです。
ステファンChazelas
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.