C 如何在Unix中设置O_非阻塞标志
我正在为类编写一个发送器/读取器IPC程序,并且我在将O_NONBLOCK标志设置为0时遇到了问题,因此当读取器试图读取的缓冲区为空时,读取器将阻塞。以下是我正在使用的函数:C 如何在Unix中设置O_非阻塞标志,c,unix,ipc,nonblocking,flags,C,Unix,Ipc,Nonblocking,Flags,我正在为类编写一个发送器/读取器IPC程序,并且我在将O_NONBLOCK标志设置为0时遇到了问题,因此当读取器试图读取的缓冲区为空时,读取器将阻塞。以下是我正在使用的函数: int set_nonblock_flag(int desc, int value) { int oldflags = fcntl(desc, F_GETFL, 0); if (oldflags == -1) return -1; if (va
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);
}
main()
main()
{
int-fd[2],n字节;
char readbuff[26];
int r_pid=0;
int s_pid=0;
/*这是所有更新*/
fd[0]=打开(“fd.txt”,仅限ordu);
fd[1]=打开(“fd.txt”,仅限O_wr);
设置非块标志(fd[0],0);
设置非块标志(fd[1],0);
/*结束更新*/
管道(fd);
r_pid=fork();
如果(r_pid<0)/*错误*/
{
fprintf(stderr,“分叉接收器失败\n”);
出口(-1);
}
否则,如果(r_pid==0)/*这是接收器*/
{
fprintf(stdout,“我,%d是接收器!\n”,getpid());
关闭(fd[1]);/*关闭写入端*/
n字节=读取(fd[0],readbuff,1);
printf(“非阻塞标志=%d\n”,fcntl(fd,F_GETFL,0));
printf(“n字节读取:%d\n”,n字节);
}
…/*已删除函数的其余部分*/
行printf(“非阻塞标志=%d\n”,fcntl(fd,F_GETFL,0));
正在返回-1作为标志状态。如果清除它,它不应该是0吗?您正在调用set\u nonblock\u标志,第一个参数是int数组。
这是fcntl手册页的一个片段。第一个参数应该是文件描述符
概要
#include <fcntl.h>
int fcntl(int fildes, int cmd, ...);
谢谢!这确实解决了我的警告问题,但现在标志被设置为2。你知道问题的原因吗?我认为你的if条件是错误的。而不是
if(value!=0)
你想要if(value==0)
。它仍然是错误的2@Zach:如果从fcntl()
返回-1,则应查看errno
(可能通过strerror()
)查看问题所在。可能是EBADF(错误的文件描述符)例如,您传递的值不是有效的打开文件描述符。在您显示的代码片段中,您没有初始化文件描述符,因此有两个不确定的数字作为文件描述符。返回的错误表明您很幸运,其中没有有效的文件描述符,因此代码失败。@jonathanleff呃,谢谢你,刚刚打印出返回的是什么,它是-1。我对C非常陌生,所以我不知道如何发送正确的文件描述符。如果你看看我更新的主代码,我将fd[0]和fd[1]设置为具有不同权限标志的同一个.txt文件,但我仍然得到-1。你能告诉我我做错了什么吗?
#include <fcntl.h>
int fcntl(int fildes, int cmd, ...);
int fd[2];
...
pipe(fd);
set_nonblock_flag(fd[0], 0);