Dapat $! menyebabkan kondisi lomba ketika digunakan dalam skrip yang berjalan secara paralel?

8

Katakanlah saya memiliki beberapa skrip bash yang berjalan secara paralel, dengan kode seperti berikut:

#!/bin/bash

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

Apakah $!dijamin memberi saya PID tugas latar belakang terbaru dalam skrip itu , atau apakah itu tugas latar belakang terbaru secara global? Saya hanya ingin tahu jika mengandalkan fitur ini dapat menyebabkan kondisi balapan ketika PID yang dikembalikannya berasal dari proses yang dimulai pada skrip lain.

philraj
sumber

Jawaban:

16

$!dijamin memberi Anda pid dari proses di mana shell dieksekusi tailperintah itu. Shell adalah single threaded, setiap shell hidup dalam prosesnya sendiri dengan set variabelnya sendiri. Tidak ada cara yang $!satu shell akan bocor ke shell lain, seperti menetapkan variabel shell dalam satu shell tidak akan mempengaruhi variabel dengan nama yang sama di shell lain (jika kita mengesampingkan variabel yang universal dari fishshell) .

Sekarang, tail -f /dev/nulladalah perintah yang berjalan tanpa batas waktu, tetapi untuk perintah yang berumur pendek, perhatikan bahwa karena ada sejumlah id proses yang mungkin terbatas, id proses akhirnya akan digunakan kembali.

Di:

true &
pid=$!

Itu $pidakan berisi id dari proses di mana shell berlari true, tetapi pada saat Anda menggunakannya $pid, pid itu mungkin sudah mati dan bisa merujuk ke proses yang berbeda.

Stéphane Chazelas
sumber
3
Yap, saya menyadari poin kedua Anda, dan bahwa jika Anda ingin membuat manajer proses latar belakang yang andal, Anda perlu menggunakan bahasa yang menjamin Anda akan tahu saat yang tepat ketika proses anak keluar dan PID-nya telah dikembalikan ke kolam , yang ternyata shell script tidak bisa karena mereka menuai proses anak secara agresif. Terima kasih atas penjelasan yang jelas.
philraj
5
@ philraj, di zsh, Anda dapat menginstal penangan di SIGCHLD yang diproses saat pemutusan pekerjaan asinkron dan digunakan $jobstate/$jobtextuntuk memeriksa status proses di sana. Bukan tanpa perlombaan karena anak sudah menuai pada saat jebakan dieksekusi, tetapi itu berarti jendela balapan yang sangat pendek di mana pids sangat tidak mungkin untuk digunakan kembali.
Stéphane Chazelas