2013-10-25 42 views
1

我有兩個進程A和B.通信流總是A→B,但我需要使用命名管道進行,因爲我必須使用管道文件描述符在B進程內部的select調用中,當任何或兩個進程退出時,寫入管道的數據必須保持不變。在非阻塞模式下使用fifo打開選擇

管道在兩端都以非阻塞模式打開。在方法A:

int push_fifo_fd = open(FIFO_NAME, O_WRONLY | O_NONBLOCK | O_CREAT, 0644); 

在方法B:

int fd = open(FIFO_NAME, O_RDONLY | O_NONBLOCK | O_CREAT, 0644); 

Q1。 進程B使用curl多接口,所以我得到curl多句柄的fd_sets,並將「fd」描述符添加到讀取fd_set中,而不是調用select來獲取文件描述符以供讀取和寫入。在每次調用select時,「fd」都包含在讀取fd_set的結果中,但即使打開寫入結束,read也會返回0。這會導致進程B使用100%的處理器時間。我提到,我不知道訂購管道的末端是否打開。從B相關代碼:

while (1) 
{ 
    fd_set read_fds, write_fds, err_fds; 

    FD_ZERO(&read_fds); 
    FD_ZERO(&write_fds); 
    FD_ZERO(&err_fds); 

    FD_SET(fifo_fd, &read_fds); 
    // some code 
    ccode = curl_multi_fdset(curlm, &read_fds, &write_fds, &err_fds, &max_fd); 
    max_fd = MAX(max_fd, fifo_fd); 

    rc = select(max_fd + 1, &read_fds, &write_fds, &err_fds, &timeout); 
    switch (rc) 
    { 
     case -1: 
      WARN("select"); 
      continue; 

     case 0: 
     default: 
      { 
       if (FD_ISSET(fifo_fd, &read_fds)) 
       { 
        // read from the fifo_fd 
       } 

       /* Now look at the handles that need attention */ 
       int old_running_handles = running_handles; 

       ccode = curl_multi_perform(curlm, &running_handles); 
       if (ccode != CURLM_OK && ccode != CURLM_CALL_MULTI_PERFORM) 
       { 
        WARN("curl_multi_perform error: %s", curl_multi_strerror(ccode)); 
        continue; 
       } 

       if (running_handles != old_running_handles) 
       { 
        CURLMsg *curl_msg; 
        int left_msgs = 0; 
        while ((curl_msg = curl_multi_info_read(curlm, &left_msgs)) != NULL) 
        { 
         // treat each easy handle 
        } 
       } 
      } 
      break; 
    } 
} 

Q2。在「man 7 fifo」中表示「進程可以在非阻塞模式下打開一個FIFO,在這種情況下,即使在寫入端沒有人打開,只讀打開也會成功,打開只寫將會失敗與ENXIO(沒有這樣的設備或地址),除非另一端已經打開。「但進程A總是能夠以非阻塞模式成功打開管道的寫入端,即使讀取端未打開。這是爲什麼?我測試的平臺是Ubuntu服務器12.04.3,內核3.8.0-29。

回答

0

因爲:

在Linux下,打開一個FIFO的讀寫都將在阻塞和非阻塞模式取得成功。 POSIX使這個行爲不確定。這可以用來打開FIFO來寫入,而沒有可用的閱讀器。爲了與自己進行通信而使用連接的兩端都應該非常小心以避免死鎖。

http://linux.die.net/man/7/fifo