Linux 文件阻塞跟非阻塞

阻塞跟非阻塞都是属于文件的属性,并非调用函数的属性。
普通文件 ==> 非阻塞
终端 ==> 阻塞

可以通过open来设置对应打开文件的属性。

阻塞

#include <stdint.h>
#include <string.h>
#include <errno.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>

#define SIZE 10

int main()
{
 	char temp[SIZE] = " 0 ";
 
 	if(0 > read(STDIN_FILENO, temp, SIZE))	//阻塞从终端输入
 	{
  		perror("read");
 	}
 	else
 	{
  		if(0 > write(STDOUT_FILENO, temp, strlen(temp)))	//输出到终端
  		{
   			perror("write");
  		}
 	}
 return 0;
}

执行以上代码会出现一个问题:
在这里插入图片描述
输入hell world
输入字节小于等于SIZE时可以正常输出,当大于SIZE时会出现如下情况:
在这里插入图片描述大于SIZE的字节会当终端指令来执行。
为什么:
因为再没有执行 exeFile应用程序时,bash(终端)属于前台程序,当./exeFile后,exeFile属于前台程序,阻塞等待输入,当入字节数大于SIZE后,按下回车键后,read会读SIZE个大小的字节到temp中,其它的还会保留再缓冲区中,当exeFile执行完后回到bash,bash发现缓存区有数据会直接取出来执行,导致如上结果。1

非阻塞

#include <stdint.h>
#include <string.h>
#include <errno.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>

#define SIZE 10

int main()
{
 char temp[SIZE] = " 0 ";
 
 int f_headle = -1;
 
 /* /dev/tty 为当前打开的终端文件,O_NONBLOCK打开设置为非阻塞属性 */
 f_headle = open("/dev/tty", O_RDONLY|O_NONBLOCK);
 if(0 > f_headle)
 {
  perror("open");
  return -1;
 }
while(1)
  {
   if(0 > read(f_headle, temp, SIZE))
   {
   /* errnor == EAGAIN信号时表示没读到数据 */
    if(errno != EAGAIN)
   {
    perror("read");
    return -1;
   }
   printf("NOT INPUT\n");
   sleep(3);
  }
  else
   break;
 }
 if(0 > write(STDOUT_FILENO, temp, strlen(temp)))
 {
  perror("write");
  return -1;
 }
 close(f_headle);
 return 0;
}

猜你喜欢

转载自blog.csdn.net/weixin_42411048/article/details/106605114