繁体   English   中英

linux select() 系统调用如何监控两个文件(文件描述符)以及如何使用定时器参数

[英]how linux select() system call monitor two files(file descriptors) and how to use timer argument

我需要使用select系统调用,我必须打开两个文件(文件描述符)并对那些准备好的文件进行读取操作,我需要在每 5 毫秒后使用一些超时并从这些文件中读取这里是我的示例代码:

int main()
{

    fd_set readfds,writefds;
    ssize_t nbytes,bytes_read;
    char buf[20];
    int fd_1,fd_2,retval;
    struct timeval tv;

    fd_1 = open("test1.txt", O_RDWR);
    if(fd_1 < 0) {
        printf("Cannot open file...\n");
        return 0;
    }

    fd_2 = open("test2.txt", O_RDWR);
    if(fd_2 < 0) {
        printf("Cannot open file_2...\n");
        return 0;
    }

    /* Wait up to five seconds. */
    tv.tv_sec = 5;
    tv.tv_usec = 0;

    for(;;)
    {
        retval = select(FD_SETSIZE, &readfds, &writefds, NULL, &tv);
        printf("select");
        perror("select");
        exit(EXIT_FAILURE);

        //}
        for(int i=0; i < FD_SETSIZE; i++)
        {
            FD_ZERO(&readfds);
            if (FD_ISSET(i, &readfds))
            {
                // read call happens here //
                nbytes = sizeof(buf);
                bytes_read = read(i, buf, nbytes);
                printf("%ld", bytes_read);
            }
            else
            {
                perror("read");
                exit(EXIT_FAILURE);
            }
        }
    }

您需要在调用select()之前初始化文件描述符集。 使用您当前的代码selectEBADF结束。

像这样的事情应该这样做:

FD_ZERO (&writefds);

for(;;)
{
    FD_ZERO (&readfds);
    FD_SET(fd_1, &readfds);
    FD_SET(fd_2, &readfds);

    retval = select(FD_SETSIZE, &readfds, &writefds, NULL, &tv);
    if (retval < 0) {
        perror("select");
        exit(EXIT_FAILURE);
    }

    for(int i=0; i<FD_SETSIZE; i++)
    {
        if (FD_ISSET(i, &readfds))
        {
            // read call happens here //
            printf("reading from file: %d\n", i);

            nbytes = sizeof(buf);
            bytes_read = read(i, buf, nbytes);
            printf("read %ld bytes\n", bytes_read);
        }
    }
}

而且您可能还想检查for(;;)循环并仅在出错时退出。 一旦您的select行为正常,您就可以在第二个for循环中继续调试。 您似乎没有在这里使用writefds ,因此您也可以在select中将其设置为NULL

还有一点要注意:由于读取集中只有两个文件,因此您可以简单地检查FD_ISSET(fd_1) / FD_ISSET(fd_2)而不是遍历所有FD_SETSIZE条目。

暂无
暂无

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

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