管道和选择:示例代码不起作用

发布于 2024-10-19 22:33:12 字数 972 浏览 0 评论 0原文

我错过了什么吗?

我想通过在另一个线程中调用 write 来退出 select...它永远不会退出 select。

代码在 OSX Snow 上进行了测试。

fd_set 里约、wio;

int pfd[2];

无效测试(int sleep_time)
{
睡眠(睡眠时间);

char buf[] = "1";

write(pfd[1], buf, 1);

}

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

{

char buff[80];
int ended = 0;

pipe(pfd);

FD_ZERO(&rio);
FD_ZERO(&wio);

FD_SET(pfd[1], &wio);   
FD_SET(pfd[0], &rio);

pthread_t tid; /* the thread identifier */
pthread_attr_t attr; /* set of thread attributes */
pthread_attr_init(&attr);

pthread_create(tid, NULL, test, 3);

while (!ended)
{
// Check my numbers ... they do not go over 1 ... so 2
if (select(2, &rio, &wio, NULL, 0) < 0)
    perror("select");
else
{
    if (FD_ISSET(pfd[1], &wio))
    {
        if ((read(pfd[0], &buff, 80))<0) 
               perror("read");
         ended = 1;
    }
 }

}

Am I missing something ?

I want to come out of select by calling write in another thread... It never comes out of select.

Code is tested on OSX snow.

fd_set rio, wio;

int pfd[2];

void test(int sleep_time)
{
sleep(sleep_time);

char buf[] = "1";

write(pfd[1], buf, 1);

}

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

{

char buff[80];
int ended = 0;

pipe(pfd);

FD_ZERO(&rio);
FD_ZERO(&wio);

FD_SET(pfd[1], &wio);   
FD_SET(pfd[0], &rio);

pthread_t tid; /* the thread identifier */
pthread_attr_t attr; /* set of thread attributes */
pthread_attr_init(&attr);

pthread_create(tid, NULL, test, 3);

while (!ended)
{
// Check my numbers ... they do not go over 1 ... so 2
if (select(2, &rio, &wio, NULL, 0) < 0)
    perror("select");
else
{
    if (FD_ISSET(pfd[1], &wio))
    {
        if ((read(pfd[0], &buff, 80))<0) 
               perror("read");
         ended = 1;
    }
 }

}

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

以酷 2024-10-26 22:33:12

我相信你有 2 个错误:

1 - 你的 select 调用将检查限制为最大 fd 2,其中管道可能会有更大的 FD,因为 0、1 和 2 已经为 stdin、stdout、stderr 打开。管道 FD 可能有 fd 3 和 4,因此您实际上需要确定 2 个管道 FD 中较大的一个,并将其用作 select 中的限制,而不是 2。

int maxfd = pfd[1];
if( pfd[0] > maxfd ) {
    maxfd = pfd[0];
}
...

2 - select 返回后,您正在查看 wio 和 pipeline当您需要查看是否有任何内容可供读取时,请写入 FD:

        if (FD_ISSET(pfd[0], &rio)) {

I believe you have 2 errors:

1 - your select call is limiting the check to a max of fd 2, where the pipe will probably have larger FDs since 0, 1, and 2 are already opened for stdin, stdout, stderr. The pipe FDs will presumably have fds 3 and 4 so you actually need to determine the larger of the 2 pipe FDs and use that for the limit in the select instead of 2.

int maxfd = pfd[1];
if( pfd[0] > maxfd ) {
    maxfd = pfd[0];
}
...

2 - After select returns, you are looking at the wio and pipe write FD when you need to instead look to see if there is anything available to READ:

        if (FD_ISSET(pfd[0], &rio)) {
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文