【问题标题】:How to set O_NONBLOCKING flag in Unix如何在 Unix 中设置 O_NONBLOCKING 标志
【发布时间】:2016-01-25 01:28:51
【问题描述】:

我正在为类编写一个发送器/读取器 IPC C 程序,并且我在将 O_NONBLOCK 标志设置为 0 时遇到问题,这样当我的读取器尝试读取的缓冲区为空时,它就会阻塞。以下是我正在使用的功能:

int set_nonblock_flag(int desc, int value)
{
        int oldflags = fcntl(desc, F_GETFL, 0);
        if (oldflags == -1)
                return -1;
        if (value != 0)
                oldflags |= O_NONBLOCK;
        else
                oldflags &= ~O_NONBLOCK;
        return fcntl(desc, F_SETFL, oldflags);
}

ma​​in()

main ()
{
        int fd[2], nbytes;
        char readbuff[26];
        int r_pid = 0;
        int s_pid = 0;

        /* THIS IS ALL UPDATED!*/
        fd[0] = open("fd.txt",O_RDONLY);
        fd[1] = open("fd.txt",O_WRONLY);
        set_nonblock_flag(fd[0], 0);
        set_nonblock_flag(fd[1], 0);
        /* END UPDATES */

        pipe(fd);

        r_pid = fork();
        if (r_pid < 0) /* error */
        {
                fprintf( stderr, "Failed to fork receiver\n" );
                exit( -1 );
        }
        else if (r_pid == 0) /* this is the receiver */
        {
                fprintf( stdout, "I, %d am the receiver!\n", getpid() );

                close( fd[1] ); /* close write end */
                nbytes = read( fd[0], readbuff, 1 );
                printf ("nonblocking flag = %d\n", fcntl(fd, F_GETFL, 0));
                printf ("Nbytes read: %d\n", nbytes );
        }

... /* rest of function removed */

printf ("nonblocking flag = %d\n", fcntl(fd, F_GETFL, 0)); 行只是返回 -1 作为标志状态。清零不应该是0吗?

【问题讨论】:

    标签: c unix ipc nonblocking flags


    【解决方案1】:

    您正在调用 set_nonblock_flag 并将第一个参数作为整数数组。 这是来自 fcntl 手册页的 sn-p。第一个参数应该是一个文件描述符。

    概要

       #include <fcntl.h>
    
       int fcntl(int fildes, int cmd, ...);
    

    描述

    fcntl() 函数应对打开的文件执行下述操作。 fildes 参数是一个文件 描述符。

    我想你想先调用管道,然后调用 set_nonblock_flag。所以,我认为你真正想要的是以下内容:

    int fd[2];
    ...
    pipe(fd);
    set_nonblock_flag(fd[0], 0);
    

    【讨论】:

    • 谢谢!这确实解决了我的警告,但现在标志设置为 2。你知道可能导致问题的原因吗?
    • 我认为你的 if 条件是错误的。而不是if (value != 0) 你想要if (value == 0)
    • 它仍然是 2
    • @Zach:如果您从fcntl() 返回-1,您应该查看errno(可能通过strerror())以了解问题所在。例如,它可能是 EBADF(坏文件描述符)。您传递的值不是有效的打开文件描述符。在您显示的代码片段中,您尚未初始化文件描述符,因此您有两个不确定的数字作为文件描述符。错误返回表明您很幸运,其中没有有效的文件描述符 - 所以代码失败。
    • @JonathanLeffler 谢谢你,刚刚打印出回报是什么,它是-1。我对C真的很陌生,所以我对如何发送正确的文件描述符感到困惑。如果您查看我更新的主代码,我将 fd[0] 和 fd[1] 设置为具有不同权限标志的同一个 .txt 文件,但我仍然得到 -1。你能告诉我我做错了什么吗?
    猜你喜欢
    • 2019-04-10
    • 2015-07-21
    • 2011-07-21
    • 1970-01-01
    • 1970-01-01
    • 2019-10-22
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多