2013-05-19 48 views
0

即時嘗試與c中的服務器客戶端進行tic tac toe遊戲。 在服務器端,我必須從FIFO(命名管道)讀取2個pid。 所以我做了一個循環,直到讀取(從fifo)返回值不同於零(意味着客戶端寫入pid到fifo)。在沒有正文的While循環中從FIFO中讀取(命名管道)

我不得不說,出於某種原因,在我的筆記本電腦上它不工作,並在我的好友筆記本電腦上工作。相同的代碼!我不知道爲什麼會發生這種情況。

當我添加一個body到第一個while循環並放一個printf(「1」);在裏面。它工作,並且pid1從FIFO中讀取pid。

服務器的代碼:

#include <stdio.h> 
#include <sys/stat.h> 
#include <fcntl.h> 
#include <unistd.h> 
#include <signal.h> 
#include <sys/ipc.h> 
#include <sys/shm.h> 
#include <string.h> 

void main() 
{ 
    int fd,shmid; 
    key_t shmkey; 
    void *shm_add; 
    pid_t pid,pid1=0,pid2=0; 
    mkfifo("fifo_clientTOserver",400); 
    fd=open("fifo_clientTOserver",O_NONBLOCK | O_RDONLY); 
    pid=fork(); 
    if(pid==0) 
    { 
     while(read(fd,&pid1,sizeof(pid_t))==0); //(1) 
    } 
    else 
    { 
     wait(); 
     while(read(fd,&pid2,sizeof(pid_t))==0) 
     { 
      if(pid2!=pid1) 
       break; 
     } 
     remove("fifo_clientTOserver"); 
    } 
    printf("\nfirst pid= %d\nsecond pid= %d\n",pid1,pid2); 
} 

客戶端的代碼:

#include <stdio.h> 
#include <sys/stat.h> 
#include <fcntl.h> 
#include <unistd.h> 
#include <signal.h> 
#include <stdbool.h> 

void my_handler(int signum); 

bool over=false; 
int board[3][3]={{0,0,0},{0,0,0},{0,0,0}}; 
char tav; 
static bool first=false; 

void main() 
{ 
    int fd; 
    pid_t pid1=getpid(); 
    signal(SIGUSR2, my_handler); 
    fd=open("fifo_clientTOserver",O_WRONLY); 
    write(fd,&pid1,sizeof(pid_t)); 
    printf("%d\n",pid1); 
    while(!over); 

} 

void my_handler(int signum) 
{ 
    char geth; 
    printf("1"); 
    //Check if the signal is SIGUSR2. 
    if (signum == SIGUSR2) 
    { 
    if(!first) 
    { 
     tav='x'; 
     printf("x"); 
     first=true; 
    } 
    else 
    { 
     tav='c'; 
     printf("c"); 
    } 
    } 
} 

這真是奇怪,我不知道如何對付它! 當我改變線(1)while(read(fd,&pid1,sizeof(pid_t))==0){printf("1");} 它的工作和pid1得到的價值。

請幫幫我。

+0

它在您的筆記本電腦上不起作用?我的意思是它卡在第1行?或者它給分段錯誤? –

+0

它的工作,但需要從第一個while循環獲得價值的pid1,不要從fifo得到價值,除非我在這個時候放置了一個body。該值僅從fifo返回到pid2 –

+1

只是出於好奇:如果在打開管道時沒有指定'O_NONBLOCK',會發生什麼? – alk

回答

0

man read

如果某些進程打開了寫作的管設置了O_NONBLOCK, 的read()將返回-1,errno設置爲[EAGAIN]。

因此,您的while循環中斷沒有任何讀取。

無論如何,繁忙的等待是不好的。放下O_NONBLOCK或使用

fd_set readfds; 
    FD_ZERO(&readfds); 
    FD_SET(fd, &readfds); 
    select(fd+1, &readfds, NULL, NULL, NULL); 

之前read()

0

當你經常在一個循環中檢查某些東西時,非阻塞和其他並行活動就會停止。通過在檢查之間進行休眠或使用I/O多路複用(選擇)可以避免繁忙的等待。

while(!AreWeThereYet()) { GetSomeSleep(); }