【问题标题】:Reading from FIFO(named pipe) in While loop without body在没有正文的While循环中从FIFO(命名管道)读取
【发布时间】:2013-05-14 04:08:55
【问题描述】:

我正在尝试用 c 语言制作一个带有服务器客户端的井字游戏。 在服务器端,我必须从 FIFO(命名管道)2 pid 中读取。 所以我做了一个循环,直到读取(从fifo)返回值不为零(意味着客户端将pid写入fifo)。

我不得不说,出于某种原因,在我的笔记本电脑上它无法正常工作,而在我的好友笔记本电脑上却可以正常工作。一样的代码!!我不知道为什么会这样。

当我在第一个 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,&amp;pid1,sizeof(pid_t))==0){printf("1");} 它正在工作,pid1 获得价值。

请帮帮我。

【问题讨论】:

  • 它在您的笔记本电脑上无法使用是什么原因?我的意思是它卡在第 1 行吗?还是给出分段错误?
  • 它可以工作,但是需要从第一个 while 循环中获取值的 pid1,除非我在 while 中放入一个主体,否则不要从 fifo 中获取值。该值仅从 fifo 返回到 pid2
  • 只是出于好奇:如果您在打开管道时不指定 O_NONBLOCK 会发生什么?

标签: c linux process while-loop pid


【解决方案1】:

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() 之前。

【讨论】:

    【解决方案2】:

    当您不断地检查循环中的某些内容时,非阻塞和其他并行活动就会变得匮乏。这种繁忙的等待可以通过在检查之间休眠或使用 I/O 多路复用 (select) 来避免。

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

    【讨论】:

      猜你喜欢
      • 2012-10-11
      • 1970-01-01
      • 2017-12-12
      • 1970-01-01
      • 1970-01-01
      • 2011-11-10
      • 2011-01-12
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多