【问题标题】:select () C lib function always returns 0select() C lib函数总是返回0
【发布时间】:2016-05-12 21:34:14
【问题描述】:

我目前正在尝试使用命名管道作为 IPC 运行服务器以同时处理多个“客户端”(本地进程)请求。客户端可以写,但是服务器上的 select() 函数似乎不能正常工作,它一直返回 0。

这是服务器的主要代码:

int main (int argc, char const *argv[]){

    fd_set set;         //fds to monitor
    Request * r;
    struct timeval tv;  //timeout
    Connection *c;      //where the fd will be saved
    fd_set foo;         //debugging purpose

    //opens the NamedPipe and saves de ReadOnly fd on c
    if( (c = openConnection()) == NULL) {
        return ERROR_OPEN_REQUEST_QUEUE;
    }

    //sets up the fds to monitor  FD_ZERO and FD_SET
    setConnection(c, &set); 

    FD_ZERO(&foo);

    tv.tv_sec = 2;
    tv.tv_usec = 0;

    while(1){

        int fdCount = select(2, &set, &foo, &foo, &tv);

            //it seems select directly modifies this value
            tv.tv_sec = 2;

            //saw it on another post        
            setConnection(c, &set); 
        if( fdCount > 0){

            r = getRequest(c);

            if( r != NULL ){
                TODO processRequest(r);
            }
        } else {
            printf("No requests to process\n");
        }
    }
    return 0;
}

服务器和客户端都使用 openConnection 从 NamedPipe 获取 fd。 openConnections 调用这个函数并创建一个连接对象:

int * openNamedPipe(char * name) {
  char origin[] = "/tmp/";
  char myfifo[80];
  int * fd;
  fd = malloc(sizeof(int)*2);

  strcpy(myfifo,origin);
  strcat(myfifo,name);
  mkfifo(myfifo, 0777);

  fd[0] = open(myfifo, O_RDONLY|O_NONBLOCK);
  fcntl(fd[0], F_SETFL, fcntl(fd[0], F_GETFL) &~O_NONBLOCK);
  fd[1] = open(myfifo, O_WRONLY);

  return fd;
}

我的问题如下:

  • 在同一管道上为每个客户端多次调用 mkfifo() 是否存在问题?
  • 打开/关闭管道相同

我正在用 cat 手动检查 fifo,我可以从 shell 中读取内容。因此,如果客户端能够写入,则服务器应该能够使用 ReadOnly fd 进行读取。

添加setConnection函数以防万一:

void setConnection(Connection * connection, fd_set* set){
  FD_ZERO(set);
  FD_SET(connection -> np -> fd, set);
  return;
}

【问题讨论】:

  • 你读过select man page吗?
  • 特别注意select修改了传递给它的文件描述符集!
  • 我确实有。也许我什么都没得到。
  • 是的,我读到过。这就是我在每次选择后重新设置 fds 的原因。还是我应该先做?
  • 你正在超时

标签: c pipe ipc named-pipes


【解决方案1】:

select的第一个参数应该是最高编号的文件描述符+1。您正在传递值 2,因此您的选择只关心 fds 0 和 1(如果它们设置在传递的集合中)。你的烟斗真的用这些吗?如果不是,则需要测试最高的代码并通过选择。

另一件事,如果您不想观看这些事件,您似乎应该只传递 NULL 而不是 foo

【讨论】:

  • 现在尝试:int fdCount = select(c -> np -> fd, &set, NULL, NULL, &tv);但它也不起作用。不过感谢您的回答。
  • 我忘了加1。你是我的救星。非常感谢!我花了一整天的时间来解决这个错误。你救了我!
  • 我认为这意味着 fds 的最大数量。之前是1,以防万一改成2。
  • @J.Nicastro 很高兴能提供帮助
猜你喜欢
  • 2011-08-27
  • 2012-12-02
  • 1970-01-01
  • 1970-01-01
  • 2016-07-21
  • 1970-01-01
  • 2015-06-26
  • 1970-01-01
  • 2018-09-26
相关资源
最近更新 更多