2016-10-24 61 views
10

Çatal işleminin STDOUT'ından okumaya çalışıyordum. Bununla birlikte, eğer bir borudan sonsuz bir for loop okuyorsam, borudan hiçbir veri gelmese bile (eğer yanılıyorsam lütfen beni düzeltin) beklemek yoğun olurdu ve sanırım bunu yapmak için daha iyi bir yol olmalı. sleep'un kısa aralıklarla kullanılması dışında, emin olmadığım geri aramalarla olabilir. Aşağıda, denediğim kod pasajı var.C de, meşgul beklemeden borulardan okuyabilir miyiz, geri aramalar veya başka yollar kullanıyor olabilir miyiz?

pid_t pid = fork(); 
switch (pid) { 
    case 0: 
     dup2 (pipes[1], STDOUT_FILENO); 
     dup2(pipes[1], STDERR_FILENO); 
     close(pipes[0]); 
     close(pipes[1]); 
     execv(path, args); 
     break; 
    default : 
     close(STDIN_FILENO); 
     close(STDOUT_FILENO); 
     close(STDERR_FILENO); 
     child_pid = pid; 
     signal(SIGHUP, mysighandle); 
     close(pipes[1]); 
     ssize_t nbytes; 
     for (;;) { 
      nbytes = read(pipes[0], buf, BUFSIZE); 
      if (nbytes == -1){ 
       break; 
      } 
      if (nbytes == 0) { 
       break; 
      } 
      syslog(LOG_NOTICE, "%s", buf); 

Birisi, boruları okumak için kullanılabilecek, yoğun bir şekilde beklemeden daha iyi bir yol önerebilir mi? C'da yeni başlayan bir kullanıcı olduğumdan, kod snippet'lerine yapılan göndermeler takdir edilmektedir.

Saygılarımızla. Kodunuzda

+6

Dosya tanıtıcısını engelleme olmayan moda ayarlamazsanız, 'read()' s varsayılan olarak engellenir - yani veri mevcut olana kadar engellenirse - bu nedenle orada meşgul beklemesi olmaz. –

cevap

9

, siz (en azından ben aslında bunu açıyoruz nasıl göstermediği için, bu, değil var varsayalım ) non-blocking mode için piponu ayarlamak değil ve bu yüzden read() yapıyor bir engelleme okuması. Yani, eğer herhangi bir veri mevcut değilse de, bazı süreç hala yazma için açık olan boruyu içeriyorsa, daha fazla veri mevcut olana kadar işleminizi otomatik olarak duraklatacaktır (ve daha sonra bu verileri arabelleğe okuyacaktır). Böylece, kodunuz gayet iyi çalışıyor ve değiştirmeye gerek yok.

(Aynı anda birden çok kanaldan okumak istemiyorsanız veya aynı iş parçacığında başka bir şey yaparken verileri beklemediğiniz sürece, bu durumda select() ve (muhtemelen) engellemeyi kullanmalısınız. I/O.)