Can $! causare condizioni di competizione quando utilizzato negli script in esecuzione in parallelo?


8

Supponiamo che io abbia più script bash eseguiti in parallelo, con codice simile al seguente:

#!/bin/bash

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

È $!garantito che mi dia il PID dell'attività in background più recente in quello script o è l'attività in background più recente a livello globale? Sono solo curioso di sapere se fare affidamento su questa funzionalità può causare condizioni di competizione quando il PID che restituisce proviene da un processo avviato in un altro script.

Risposte:


16

$!è garantito per darti il ​​pid del processo in cui la shell ha eseguito quel tailcomando. Le conchiglie sono a thread singolo, ogni shell vive nel proprio processo con il proprio set di variabili. Non è possibile che la $!shell di una shell si riversi in un'altra shell, proprio come assegnare una variabile di shell in una shell non influirà sulla variabile con lo stesso nome in un'altra shell (se mettiamo da parte le variabili universali della fishshell) .

Ora, tail -f /dev/nullè un comando che viene eseguito indefinitamente, ma per comandi di breve durata, notare che poiché esiste un numero limitato di possibili ID di processo, gli ID di processo finiscono inevitabilmente per essere riutilizzati.

In:

true &
pid=$!

Questo $pidconterrà l'id del processo in cui il guscio Ran true, ma per il momento si utilizza tale $pid, che PID può anche essere morto e potrebbe riferirsi ad un processo diverso.


3
Sì, ero a conoscenza del tuo secondo punto e che se desideri creare un gestore di processi in background affidabile devi utilizzare un linguaggio che garantisca che conoscerai il momento esatto in cui un processo figlio è uscito e il suo PID è stato restituito al pool , che a quanto pare shell script non possono poiché raccolgono i processi figlio in modo aggressivo. Grazie per la chiara spiegazione.
philraj,

5
@philraj, in zsh, è possibile installare gestori su SIGCHLD che vengono elaborati al termine di lavori asincroni e utilizzati $jobstate/$jobtextper controllare lo stato del processo. Non senza razza poiché il bambino è già stato raccolto al momento dell'esecuzione della trappola, ma ciò significa finestre di gara molto brevi in ​​cui è molto improbabile che i pids siano già riutilizzati.
Stéphane Chazelas,
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.