【问题标题】:pthreads: wait until read() returns a value > 0pthreads:等到 read() 返回值 > 0
【发布时间】:2016-01-09 10:44:45
【问题描述】:

我正在开发一个客户端程序,它将作为基本的即时通讯工具运行。我正在使用 pthread 打开一个线程,专门用于等待接收消息和读取消息。使用 pthread_cond_wait 是等待read(sockfd, buffer, 256) 高于 0 的正确方法吗?

void *threadRead() {
  while (1) {
    bzero(buffer,256);
    pthread_cond_wait(&buffer_lock, read(sockfd, buffer, 255) > 0);
    n = read(sockfd, buffer, 255);
    printf("%s\n",buffer);
  }
}

您知道,我只需要等到read() 返回高于0 的值即可继续,但我找不到合适的系统来执行此操作。如果有人可以链接一些能让我走上正轨的东西或给我一个很好的提示。

【问题讨论】:

  • 这不是你的做法。您需要使用select() 等待套接字上的输入。

标签: c multithreading pthreads conditional-statements wait


【解决方案1】:

你应该改用select(),像这样

int running;
running = 1;
while (running != 0) /* Just in case you want to end the loop, you can */
{
    fd_set rdset;
    struct timeval timeout;

    timeout.tv_sec = NUMBER_OF_SECONDS_TO_WAIT;
    timeout.tv_usec = YOU_CAN_HAVE_MICRO_SECONDS_PRECISION;

    FD_ZERO(&rdset);
    FD_SET(fd, &rdset);
    if (select(fd + 1, &rdset, NULL, NULL, &timeout) == 1)
    {
        ssize_t length;
        char buffer[100];
        length = read(fd, buffer, sizeof(buffer));
        /* use buffer now */
    }
    else
    {
        /* Timed out and still nothing to read */
        /* do something meanwhile and retry if */
        /* you want to.                        */
    }
    running = use_a_function_to_check_this();
}

你可以在不同的线程中使用它,但你需要小心。

非阻塞 IO 很难,不管你如何实现它都很难。

还有一件事,这个

n = read(sockfd, buffer, 255);
printf("%s\n",buffer);

可能是未定义的行为,因为显然缓冲区是

char buffer[256];

你可以

n = read(sockfd, buffer, 255 /* or sizeof(buffer) - 1 */);
buffer[n] = '\0';

printf("%s\n",buffer);

确保buffernul 终止。

【讨论】:

  • 我要做的就是读出消息何时以及是否来自服务器到客户端。端口号和套接字都处理好了,我只需要一些方法来检测消息是否已发送,如果没有,则等待消息到来。然后打印出来。我不确定这段代码是如何做到的。
  • 如果您将NULL 传递给select() 作为超时参数,它将等待直到有内容要读取。看手册就明白了,linux的话要特别注意细节。
  • 好吧,我越读手册越明白,我只是对整个 fd+1 部分感到困惑,你从哪里得到 fd?
  • 这是套接字,你用来写入套接字的文件描述符。您应该将集合中文件描述符的最大值 + 1 传递给select()
【解决方案2】:

没有。 pthread_cond_wait() 用于等待将由您的其他线程之一更改的条件。

如果您只是想等待read() 返回一些东西,只需致电read()。除非你明确将套接字标记为非阻塞,否则它将阻塞调用线程,直到有东西要返回。

如果read() 曾经返回 0,则表示文件结束:这意味着套接字已在远程端关闭,因此将永远不会再读取。

【讨论】:

  • 在 while 循环中调用 read() 在系统上似乎非常密集。我只是在寻找某种方法来读出缓冲区/消息是否以及何时通过。
  • 如果它阻塞等待不是密集的,它只是阻塞。你也可以随时睡觉!
  • @user3475821:不是——阻塞意味着调用线程被挂起,直到某个事件发生(在这种情况下,直到套接字上有活动)。
  • @caf 听起来就像我正在寻找的东西,但我找不到您正在谈论的特定功能。我所看到的一切都需要另一个线程或函数来传递信号或通知。我只是在等待一个值出现。
  • @user3475821:read() 函数本身 - 只要套接字是阻塞的,这是默认设置 - 就会这样做。 (如果socket是非阻塞的,可以使用select()或者poll())。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2019-03-24
  • 1970-01-01
  • 2017-03-21
  • 1970-01-01
  • 2016-03-18
  • 2013-02-07
  • 1970-01-01
相关资源
最近更新 更多