阻塞跟非阻塞都是属于文件的属性,并非调用函数的属性。
普通文件 ==> 非阻塞
终端 ==> 阻塞
可以通过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;
}