Quale distribuzione di probabilità modella questa condizione di razza?


10

Si consideri il seguente comando: bash -c "echo x; cat 1" | tee 1.

La mia comprensione è che sarebbe fork su una nuova shell, scrivere xsu stdout, scrivere file 1 not foundsu stderr, uscire e restituire il controllo al processo genitore e scrivere xsu stdout e su 1. Quindi, mi aspetto che l'output finale sia xe il file 1contiene esattamente la stringa x.

Tuttavia, questo non è il caso. In realtà, il file di 1solito contiene almeno due istanze di x, e talvolta migliaia di righe di xs. In un test batch di esecuzione del comando diecimila volte, il numero medio di xs scritte nel file era 52.3 e la mediana era 1. Quale meccanico sta causando questo? Quale distribuzione di probabilità modella questo comportamento? Sospetto che sia condizionatamente geometrico e altrimenti uniforme.


3
Ha a che fare con la tempistica dell'esecuzione del lato sinistro e destro della condotta. Entrambi vengono avviati contemporaneamente o vicini ad esso. Se teeil file è stato aperto per la scrittura prima di cataprirlo per la lettura, è possibile che siano presenti molti xfile nel file. In tal caso, il "ciclo" terminerebbe ogni volta che catlegge più velocemente delle teescritture, raggiungendo la fine del file.
Kusalananda

Dai test limitati qui, il numero medio di messaggi xscritti nel file era di 4,35. Immagino che dipenderà molto dal carico della macchina.
Renan,

Risposte:


1

Questo è molto curioso, quindi ho cercato di investigarlo con l'aiuto di Strace. Esegui il tuo comando in un ciclo 1000 volte:

mkdir {000..999}
for i in {000..999}; do
echo $i
(cd $i; strace -f -o trace.log bash -c 'bash -c "echo x; cat 1" | tee 1 >/dev/null'; )
done

Trovato il file con il maggior numero di righe ( wc -l */1 | sort -nr | head -n2) e verificato il corrispondente trace.log. Posso sicuramente vedere molti:

7567  <... read resumed> "x\n", 8192)   = 2
7567  write(1, "x\n", 2)                = 2
7567  write(3, "x\n", 2)                = 2
7567  read(0,  <unfinished ...>
7568  read(3, "x\n", 131072)            = 2
7568  write(1, "x\n", 2)                = 2
7567  <... read resumed> "x\n", 8192)   = 2
7567  write(1, "x\n", 2)                = 2
7567  write(3, "x\n", 2)                = 2
7567  read(0,  <unfinished ...>
7568  read(3, "x\n", 131072)            = 2
7568  write(1, "x\n", 2)                = 2
7567  <... read resumed> "x\n", 8192)   = 2
7567  write(1, "x\n", 2)                = 2
7567  write(3, "x\n", 2)                = 2
7567  read(0,  <unfinished ...>

Dove è 7567 tee 1e 7568 è cat 1. I due si stanno decisamente alternando, quindi sì, come sospettato, si tratta solo del tempismo dell'esecuzione (e immagino il cambio di contesto) dei due comandi.

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.