简体   繁体   English

在没有主体的情况下从While循环中的FIFO(命名管道)读取

[英]Reading from FIFO(named pipe) in While loop without body

im trying to make a tic tac toe game with server-client in c. 我正在尝试用c中的服务器-客户端制作井字游戏。 On the server side i have to read from FIFO(named pipe) 2 pids. 在服务器端,我必须从FIFO(命名管道)中读取2个pid。 so i made a loop that run until the read (from fifo) return value different from zero(mean that the client wrote pid to the fifo). 所以我做了一个循环,直到读取(从fifo)返回的值不同于零(意味着客户端将pid写入FIFO为止)。

I have to say that for some reason, on my laptop it's not working and on my buddy laptop it's working. 我不得不说,由于某种原因,我的笔记本电脑无法正常工作,而我的伙伴笔记本电脑却可以正常工作。 The same code!! 相同的代码! I have no clue why this is happening. 我不知道为什么会这样。

And when i add a body to the first while loop and put a printf("1"); 当我在第一个while循环中添加一个主体并放置一个printf(“ 1”); in it. 在里面。 it's work and the pid1 reads the pid from the FIFO. 它正在工作,并且pid1从FIFO读取pid。

The code of the server: 服务器代码:

#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);
}

The code of the Client: 客户代码:

#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");
    }
    }
}

It's really weird and i dont know how to deal with it! 这真的很奇怪,我不知道该如何处理! When i change line (1) to while(read(fd,&pid1,sizeof(pid_t))==0){printf("1");} it's working and pid1 get the value. 当我将行(1)更改为while(read(fd,&pid1,sizeof(pid_t))==0){printf("1");}它正在工作,而pid1获得该值。

Please help me. 请帮我。

man read : man read

If some process has the pipe open for writing and O_NONBLOCK is set, read() shall return -1 and set errno to [EAGAIN]. 如果某个进程打开了用于写入的管道,并且设置了O_NONBLOCK,则read()将返回-1并将errno设置为[EAGAIN]。

So, your while loop breaks without anything read. 因此,您的while循环中断,但未读取任何内容。

In any event, busy waiting is bad. 无论如何,繁忙的等待是不好的。 Drop the O_NONBLOCK or use 放下O_NONBLOCK或使用

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

before the read() . read()之前。

When you are constantly checking something within a loop, non-blocking and other parallel activities are starved. 当您不断检查循环中的某些内容时,无阻塞的活动和其他并行活动就会饿死。 This busy waiting can be avoided by sleeping between checks or using I/O multiplexing (select). 可以通过在两次检查之间休眠或使用I / O复用(选择)来避免这种繁忙的等待。

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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM