2011-03-03 62 views
0

我錯過了什麼嗎?管道和選擇:示例代碼不起作用

我想通過在另一個線程中調用寫入來選擇出來......它從來沒有出來選擇。

代碼在OSX雪中測試。

fd_set rio,wio;

int pfd [2];

空隙測試(INT SLEEP_TIME)
{
睡眠(SLEEP_TIME);

char buf[] = "1"; 

write(pfd[1], buf, 1); 

}

INT主(INT ARGC,CHAR *的argv [])

{

char buff[80]; 
int ended = 0; 

pipe(pfd); 

FD_ZERO(&rio); 
FD_ZERO(&wio); 

FD_SET(pfd[1], &wio); 
FD_SET(pfd[0], &rio); 

pthread_t tid; /* the thread identifier */ 
pthread_attr_t attr; /* set of thread attributes */ 
pthread_attr_init(&attr); 

pthread_create(tid, NULL, test, 3); 

while (!ended) 
{ 
// Check my numbers ... they do not go over 1 ... so 2 
if (select(2, &rio, &wio, NULL, 0) < 0) 
    perror("select"); 
else 
{ 
    if (FD_ISSET(pfd[1], &wio)) 
    { 
     if ((read(pfd[0], &buff, 80))<0) 
       perror("read"); 
     ended = 1; 
    } 
} 

}

回答

1

我相信你有2個錯誤:

1 - 你的select調用將檢查限制爲fd 2的最大值,其中管道可能具有較大的FD,因爲0,1和2已針對stdin,stdout和stderr打開。該管道將​​函數依賴大概有FDS 3和4,因此您的實際需要來確定2個文件描述符的較大和使用的限制在選擇而不是2

int maxfd = pfd[1]; 
if(pfd[0] > maxfd) { 
    maxfd = pfd[0]; 
} 
... 

2 - select返回後,正在看wio和管道寫FD當你需要,而不是看看是否有什麼可供閱讀:

 if (FD_ISSET(pfd[0], &rio)) {