高级I/O总结(一):基础

重要概念

同步通信 VS 异步通信

概念:

(1)同步通信的不足

  • 等待

  • 接口耦合性

  • 网络位置耦合性

  • 可用性耦合性

总结: 耗时 + 耦合度比较高。

(2)异步通信

  • 无等待

  • 面向消息解耦合

  • 位置独立

  • 确保投递

总结:解决了同步通信的不足。

在这里插入图片描述

阻塞 VS 非阻塞

(1)阻塞是指调用结果返回之前,当前线程会被挂起,线程只有在得到结果之后才会返回。

(2)非阻塞没有立即得到结果,不会阻塞当前线程,会立即返回,常常用轮询方式处理。

分布式锁机制

1、单机时代;


2、多机集群、分布式时代。

I/O模型

(1)阻塞IO
(2)非阻塞IO
(3)信号驱动IO
(4)IO多路转接
(5)异步IO

非阻塞IO

fcntl

一个文件描述符,默认都是阻塞IO。

函数原型:

#include<unistd.h>
#include<fcntl.h>
int fcntl(int fd, int cmd, .../* arg */);

fcntl根据传入的cmd参数不同,可以实现5种功能,此处只用一种功能:获取/设置文件状态标记,就可以将一个文件描述符设置为非阻塞。

SetNoBlock

基于fcntl将一个文件描述符设置为非阻塞。

void SetNoBlock(int fd)
{
  int f1 = fcntl(fd, F_GETFL);
  if(f1 < 0)
  {
    perror("fcntl");
    return;
  }
  fcntl(fd, F_SETFL, f1 | O_NONBLOCK);
}   

使用F_GETFL将当前的文件描述符的属性取出来(这是一个位图);
然后使用F_SETFL将文件描述符设置回去,设置回去的同时加一个O_NONBLOCK参数。

重定向

dup/dup2系统调用

函数原型:

#include<unistd.h>
int dup(int oldfd);
int dup2(int oldfd, int newfd);
dup
#include<unistd.h>
#include<stdio.h>
#include<fcntl.h>

int main()
{
    int fd = open("./Linux", O_CREAT | O_RDWD);
    if(fd < 0)
	{
		perror("open");
		return 1;
	}
	close(1);
	int new_fd = dup(fd);
	if(new_fd != 1)
	{
		perror("dup");
		return 1;
	}
	printf("new_fd: %d\n", new_fd);
	close(fd);
	
	for(;;)
	{
		char buf[1024] = {0};
		ssize_t read_size = read(0, buf, sizeof(buf) - 1);
		if(read_size < 0)
		{
			perror("read");
			continue;
		}
		printf("%s", buf);
		fflush(stdout);
	}
	close(new_fd);
    return 0;  
}
dup2
  • 举例:
int oldfd;  
oldfd = open("app_log", (O_RDWR | O_CREATE), 0644 );  
dup2( oldfd, 1 );  
close( oldfd ); 

在本例中,我们打开了一个新文件,称为“app_log”,并收到一个文件描述符,该描述符叫做fd1。我们调用dup2函数,参数为oldfd和1,这会导致用我们新打开的文件描述符替换掉由1代表的文件描述符(即stdout,因为标准输出文件的id为1)。任何写到stdout的东西,现在都将改为写入名为“app_log”的文件中。需要注意的是,dup2函数在复制了oldfd之后,会立即将其关闭,但不会关掉新近打开的文件描述符,因为文件描述符1现在也指向它。

#include <stdio.h>  
#include <stdlib.h>  
#include <unistd.h>  
int main()  
{  
   int pfds[2];  
   if ( pipe(pfds) == 0 )
   {  
    if ( fork() == 0 ) 
    {  
        close(1);  
        dup2( pfds[1], 1 );  
        close( pfds[0] );  
        execlp( "ls", "ls", "-l", NULL );  
    }
     else 
    {  
  
        close(0);  
        dup2( pfds[0], 0 );  
        close( pfds[1] );  
        execlp( "wc", "wc", "-l", NULL );  
    }  
    return 0;  
} 
发布了150 篇原创文章 · 获赞 280 · 访问量 32万+
展开阅读全文

没有更多推荐了,返回首页

©️2019 CSDN 皮肤主题: 黑客帝国 设计师: 上身试试

分享到微信朋友圈

×

扫一扫,手机浏览