我有兩個進程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。