在五种IO模型中有提到在Linux中,默认所有的套接字都是阻塞的。所以要实现非阻塞的套接字,就要执行特定的系统调用来实现。
fcntl
函数原型:
#include <unistd.h>
#include <fcntl.h>
int fcntl(int fd, int cmd, ... /* arg */ );
参数说明:
fd:表示对哪个文件描述符进行操作
cmd:表示对文件描述符进行什么操作
arg:根据操作的不同而又不同的取值
函数功能:该函数的功能有很多,对应的cmd取值也有很多,但这里实现的只是将文件描述符设置为非阻塞。所以只介绍该部分的功能。
cmd = F_GETFL:获取文件状态标记,此时状态标记由返回值带回,参数arg为空。返回值为负数,说明获取失败。
cmd = F_SETFL:设置文件状态标记,此时新设置的文件状态标记由参数arg标识,返回值表示设置成功与否。
上述的文件状态其实是一个位图。不同的比特位表示不同的状态。不同的状态信息由不同的宏来标识。不同的宏之代表的数字之间只有一个比特位不同。O_NONBLOCK表示的就是文件的非阻塞状态。
下面通过将标准输入设置为非阻塞来使用该函数:
如果标准输入为阻塞状态,在对标准输入进行读取数据时,如果没有数据,此时进程就会被挂起等待,阻塞在相应的系统调用处,且该系统调用不返回。
如果标准输入为非阻塞状态,在对其进行读取数据时,如果没有数据,此时进程不会被挂起,而是系统调用返回后,进程可以做其他的事情。
首先编写将文件描述符设置为非阻塞的函数:
void SetNoBlock(int fd)
{
//首先利用fcntl函数获取文件描述符的文件标记状态
int flag = fcntl(fd,F_GETFL);
if(flag < 0)
{
perror("fcntl");
return;
}
//设置文件描述符的标记状态,在原有的基础上再加一个非阻塞的标记状态
fcntl(fd,F_SETFL,flag | O_NONBLOCK);
return;
}
通过将标准输入设置为阻塞和非阻塞来进行演示(标准输入默认是阻塞的):
int main()
{

本文详细介绍了如何在Linux系统中使用fcntl将文件描述符设置为非阻塞模式,以及如何利用dup2进行文件重定向。通过示例展示了在非阻塞IO下,当没有数据时进程不会被阻塞,同时讲解了dup和dup2的区别及其在文件重定向中的应用。
最低0.47元/天 解锁文章
3689

被折叠的 条评论
为什么被折叠?



