目录
三、使用fcntle将一个文件描述符从阻塞状态改为非阻塞状态
fcntle
一、函数原型
#include <fcntl.h> #include <unistd.h> int fcntl(int fd, int cmd, ... /* arg */);
fd
:需要操作的文件描述符。cmd
:要执行的操作命令,如F_DUPFD
、F_GETFD
、F_SETFD
等。arg
:根据cmd
的不同,可能需要提供额外的参数。二、功能概述
fcntl
函数主要用于对文件描述符进行以下操作:
- 复制文件描述符:
F_DUPFD
命令可以复制一个现有的文件描述符,并返回一个新的文件描述符。这个新文件描述符与原始文件描述符在底层引用的是同一个文件表项,即它们指向同一个打开的文件。- 获取/设置文件描述符标记:通过
F_GETFD
和F_SETFD
命令,可以获取或设置与文件描述符相关联的特定标记,如FD_CLOEXEC
(表示在exec调用时是否关闭该文件描述符)。- 获取/设置文件状态标记:通过
F_GETFL
和F_SETFL
命令,可以获取或设置文件描述符的状态标记,如O_NONBLOCK
(非阻塞模式)、O_APPEND
(追加模式)等。- 获取/设置异步I/O所有权:通过
F_GETOWN
和F_SETOWN
命令,可以获取或设置哪个进程或进程组将接收与文件描述符相关的异步I/O信号。- 获取/设置记录锁:通过
F_GETLK
、F_SETLK
和F_SETLKW
命令,可以对文件的某个区域进行加锁或解锁操作,以防止多个进程同时访问或修改同一文件区域。
三、使用fcntle将一个文件描述符从阻塞状态改为非阻塞状态
功能函数:
void SetNonBlock(int fd)
{
int f1 = fcntl(fd, F_GETFL);
if(f1 < 0)
{
perror("GETFL fail");
return;
}
if(fcntl(fd, F_SETFL, f1 | O_NONBLOCK) < 0)
{
perror("SETFL fial");
return;
}
}
测试例子:
#include <unistd.h>
#include <fcntl.h>
#include <iostream>
using namespace std;
void SetNonBlock(int fd)
{
int f1 = fcntl(fd, F_GETFL);
if(f1 < 0)
{
perror("GETFL fail");
return;
}
if(fcntl(fd, F_SETFL, f1 | O_NONBLOCK) < 0)
{
perror("SETFL fial");
return;
}
}
int main()
{
//将标准输入流设置为非阻塞
SetNonBlock(0);
while(1)
{
char buff[1024];
ssize_t size = read(0, buff, sizeof(buff) - 1);
if(size < 0)
{
perror("read");
sleep(1);
continue;
}
cout << "buff :" << buff << endl;
}
return 0;
}
结果: