本文共 2821 字,大约阅读时间需要 9 分钟。
可以在管道上进行非阻塞I / O吗? fcntl无法设置O_NONBLOCK.
Linux编程接口的页面918包括一个表’从管道读取n个字节或FIFO(p)’的语义.此表列出了管道和FIFO的行为,其中一列标题为O_NONBLOCK已启用?这意味着您可以在管道上设置O_NONBLOCK标志.它是否正确?以下代码无法设置标志,但fcntl(2)不报告错误.
#include
#include
#include
#include
#include
#define SLEEP 1
int
main(int argc, char *argv[]) {
pid_t childPid;
int pfd[2];
int nread, flags;
int c = 'a';
setbuf(stdout, NULL);
if (pipe(pfd) == -1) {
printf("error: pipe");
exit(EXIT_FAILURE);
}
switch (childPid = fork()) {
case -1:
printf("error: fork");
exit(EXIT_FAILURE);
case 0: /* child */
if (close(pfd[0]) == -1) {
printf("child: close pfd read");
exit(EXIT_FAILURE);
}
sleep(SLEEP);
_exit(EXIT_SUCCESS);
default:
break;
/* parent falls through */
}
if (close(pfd[1]) == -1) {
printf("parent: close pipe write");
exit(EXIT_FAILURE);
}
flags = fcntl(pfd[0], F_GETFD);
flags |= O_NONBLOCK;
if (fcntl(pfd[0], F_SETFD, flags))
perror("fcntl");
/* verify flags set correctly */
flags = fcntl(pfd[0], F_GETFD);
if (!(flags & O_NONBLOCK)) {
printf("failed to set O_NONBLOCK\n");
exit(EXIT_FAILURE);
}
wait(NULL);
exit(EXIT_SUCCESS);
}
管道和O_NONBLOCK没有什么特别之处.以下示例按预期工作.我没有检查每次调用的每个retval,以使示例更具可读性.真实世界的应用程序必须进行检查.
#include
#include
#include
#include
int main()
{
int fds[2];
pid_t pid;
char buf[100];
pipe(fds);
pid = fork();
if ( pid )
{
while (1 )
{
memcpy( buf, "abcdefghi\0",10);
write( fds[1], buf, 10);
sleep(2);
}
}
else
{
int retval = fcntl( fds[0], F_SETFL, fcntl(fds[0], F_GETFL) | O_NONBLOCK);
printf("Ret from fcntl: %d\n", retval);
while (1)
{
ssize_t r=read( fds[0], buf, 10 );
printf("read: %d\n", r);
if ( r > 0 )
{
printf("Buffer: %s\n", buf);
}
else
{
printf("Read nothing\n");
perror("Error was");
sleep(1);
}
}
}
}
写完我的例子后,我检查你的代码,发现:
flags = fcntl(pfd[0], F_GETFD);
flags |= O_NONBLOCK;
if (fcntl(pfd[0], F_SETFD, flags))
请将F_SETFD更改为F_SETFL以及get操作.您不会更改文件描述符标志,但文件描述符状态标志:-)
来自man 3 fcntl:
File descriptor flags
The following commands manipulate the flags associated with a file
descriptor. Currently, only one such flag is defined: FD_CLOEXEC, the
close-on-exec flag. If the FD_CLOEXEC bit is 0, the file descriptor
will remain open across an execve(2), otherwise it will be closed.
File status flags
Each open file description has certain associated status flags, ini‐
tialized by open(2) and possibly modified by fcntl(). Duplicated file
descriptors (made with dup(2), fcntl(F_DUPFD), fork(2), etc.) refer to
the same open file description, and thus share the same file status
flags.
F_SETFL (int)
Set the file status flags to the value specified by arg. File
access mode (O_RDONLY, O_WRONLY, O_RDWR) and file creation flags
(i.e., O_CREAT, O_EXCL, O_NOCTTY, O_TRUNC) in arg are ignored.
On Linux this command can change only the O_APPEND, O_ASYNC,
O_DIRECT, O_NOATIME, and O_NONBLOCK flags. It is not possible to change the O_DSYNC and O_SYNC flags; see BUGS, below.
转载地址:https://blog.csdn.net/weixin_28871097/article/details/116922508 如侵犯您的版权,请留言回复原文章的地址,我们会给您删除此文章,给您带来不便请您谅解!