Buradaki önemli arka plan , standart olarak varsayılan ayar olarak satır tamponlustdout
olması gerekir .
Bu \n
, çıktının yıkanmasına neden olur .
İkinci örnek newline'ı içermediğinden, çıktı boşaltılmaz ve fork()
tüm işlemi kopyaladığında, stdout
tamponun durumunu da kopyalar .
Şimdi, fork()
örneğinizdeki bu çağrılar toplamda 8 işlem yaratıyor - hepsi stdout
tamponun bir kopyasıyla birlikte .
Tanım olarak, tüm bu işlemler exit()
geri dönerken çağrılırmain()
ve ardından tüm aktif stdio akışlarında exit()
çağrılar çağrılır . Bu, içerir ve sonuç olarak, aynı içeriği sekiz kez görürsünüz.fflush()
fclose()
stdout
fflush()
Çağrılmadan önce bekleyen çıktıları olan tüm akışları çağırmak fork()
ya da çatallı çocuğun açıkça _exit()
stdio akışlarını temizlemeden yalnızca süreçten çıkmasını sağlamak için iyi bir uygulamadır .
exec()
Aramanın stdio arabelleklerini temizlemediğini unutmayın , bu nedenle (aradıktan sonra fork()
) aramayı exec()
ve (başarısız olursa) aramayı stdio arabelleklerini umursamayacağınıza dikkat edin _exit()
.
BTW: Yanlış tamponlamanın neden olabileceğini anlamak için, Linux'ta yakın zamanda düzeltilmiş olan eski bir hata:
Standart, stderr
varsayılan olarak arabelleksiz hale getirilmeyi gerektirir , ancak Linux bunu ihmal etti ve stderr
stderr'in bir boruya yönlendirilmesi durumunda hattı tamponladı ve (daha da kötüsü) tamamen tamponladı. Bu yüzden UNIX için yazılmış programlar Linux'ta çok geç yeni satır olmadan bir şeyler çıkardılar.
Aşağıdaki yoruma bakınız, düzeltildi gibi görünüyor.
Bu Linux sorunu etrafında çalışmak için yaptığım şey:
/*
* Linux comes with a broken libc that makes "stderr" buffered even
* though POSIX requires "stderr" to be never "fully buffered".
* As a result, we would get garbled output once our fork()d child
* calls exit(). We work around the Linux bug by calling fflush()
* before fork()ing.
*/
fflush(stderr);
Bu kod diğer platformlara zarar vermez, çünkü fflush()
yalnızca temizlenen bir akıntıya çağrı yapmak bir noop'tur.
./prog1 > prog1.out
) veya bir boruya (./prog1 | cat
) çıkışıyla çalıştırmayı deneyin . Aklını uçurmaya hazır ol. :-)