2017-03-08 62 views
5

'UNIX Ağ Programlama: Yuva Ağ API': buf hata açıklamasını içerirStderr'e yazmadan önce neden stfut üzerinde fflush kullanmalıyım? Okuyorum

fflush(stdout);  /* in case stdout and stderr are the same */ 
fputs(buf, stderr); 
fflush(stderr); 

ve örnek kodda aşağıdaki satırları içeren bir hata işleme fonksiyonu var. FFlush'ın neden ilk satırdaki stdoutta kullanıldığını ve yorumun neden kullanıldığını açıkladığını anlamıyorum.

cevap

11

Bunun nedeni arabelleğe alınmadır. Stdout and stderr are usually buffered differently. Stdout, genellikle satır arabelleğe alınmış, yani satırsonu görünene kadar çıktı gösterilmez. Stderr genellikle arabelleğe alınmış ve hemen yazdırılacak, düşünme hata mesajları pronto görmelisiniz. Her ikisi de aynı yere, terminale giderler. Bu, /* in case stdout and stderr are the same */ ile ne anlama geliyor. Onlar genellikle. Ancak, farklı şekilde tamponlandıkları için bu, bunların sıra dışı olarak görüntülenmesine yol açabilir. Bu kodu göz önünde bulundurun. Yeni satırların eksikliğine dikkat edin.

This is to stdout. This is to stderr. This is also to stdout. 

Ama değil:

#include <stdio.h> 

int main() { 
    fprintf(stdout, "This is to stdout. "); 
    fprintf(stderr, "This is to stderr. "); 
    fprintf(stdout, "This is also to stdout. "); 
} 

Sen çıkış olmasını beklersiniz. Düzensiz.

stderr'e çıkış hemen görüntülenir
$ ./test 
This is to stderr. This is to stdout. This is also to stdout. 

, bu tamponsuz olduğu. Stdout stdout arabelleğinin yeni satır tarafından temizlenmesini beklemek zorunda iken. Yeni satır yok, bu yüzden program çıktığında temizlendi.

Stderr'i kullanmadan önce stdout'u temizleyerek, çıktının arabelleğe alınmadan bağımsız olarak doğru sırada gelmesini sağlayın.

#include <stdio.h> 
#include <unistd.h> 

int main() { 
    fprintf(stdout, "This is to stdout. "); 
    fflush(stdout); 
    fprintf(stderr, "This is to stderr. "); 
    fprintf(stdout, "This is also to stdout. "); 
} 

$ ./test 
This is to stdout. This is to stderr. This is also to stdout. 

Bu, hata iletilerinin normal iletilerle birlikte doğru sırayla ortaya çıkmasını sağlar. Bu, hangi hata mesajının programın parçası için geçerli olduğu konusunda kafa karıştırmaz.

+0

İkinci örneğiniz yanlış; 'Bu ayrıca stdout.' ve' stdout’tur. '' Anahtarlanmalı. – Qix

+0

stderr 'uncharacteristically _line_ buffered ise, bu yanıtla giderilmeyen benzer sorunlar ortaya çıkacaktır. Pedantically, yazmadan önce diğerini yıkayın. Veya iyi görgü kuralları kullanın ve [işiniz bittiğinde yıkayın] – chux

+1

@Qix Teşekkürler. Orijinal olarak koddaki dosya elleriyle karıştırdım. – Schwern

1

Stdout ve stderr aynı dosyaya işaret ediyorsa, öncelikle stdout arabelleğinde ne yazıldığından emin olmalısınız.

İlgili konular