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);   //非阻塞模式的消息接受
Logo

腾讯云面向开发者汇聚海量精品云计算使用和开发经验,营造开放的云计算技术生态圈。

更多推荐