2021年3月31日
** read函数读取时报: Resource temporarily unavailable 原因及解决办法 **
原因有以下:可能是非阻塞模式下使用了阻塞操作;
(1)调用open()函数时,使用了非阻塞模式(O_NONBLOCK),直接用read函数读取;而read默认为阻塞操作,所以导致报错。
//读取鼠标
//要打开鼠标这个文件获取文件描述符
fd = open( "/dev/input/mouse0", O_RDONLY | O_NONBLOCK ); //非阻塞模式(O_NONBLOCK)
if( fd < 0 )
{
perror( "open fail" );
exit(0);
}
printf( "before read.\n" );
ret = read( fd, buf, 100 ); //阻塞式(错误)
if( ret < 0 )
{
perror( "read fail" );
exit(-1);
}
printf( "读出的内容是:[%s]\n", buf );
(2)使用fcntl()函数时,使用了非阻塞模式(O_NONBLOCK),直接用read函数读取;而read默认为阻塞操作,所以导致报错。
//读取键盘
//键盘就是标准输入,stdin,其文件描述符为0
//把0号文件描述符(stdin)变成非阻塞式的
flag = fcntl( 0, F_GETFL ); //先获取原来的flag
flag |= O_NONBLOCK; //添加非阻塞属性
ret = fcntl( 0, F_SETFL, flag ); //更新flag
if( ret < 0 )
{
perror( "fcntl fail" );
exit(-1);
}
printf( "before read.\n" );
ret = read( 0, buf, 2 ); //阻塞式(错误)
if( ret < 0 )
{
perror( "read fail" );
exit(-1);
}
printf( "读出的内容是:[%s]\n", buf );
解决:
(1)可将非阻塞去除,改为阻塞模式;
(2)解决read阻塞问题;
(3)阻塞情况下,客户端发送的消息服务端无法接受。改用recv替换read
将recv, send 函数的最后有一个flag 参数设置成MSG_DONTWAIT
recv(sockfd, buff, buff_size,MSG_DONTWAIT); //非阻塞模式的消息发送
send(scokfd, buff, buff_size, MSG_DONTWAIT); //非阻塞模式的消息接受