高级IO:管道与dup讲解

本文介绍了进程间通信的管道(Pipe)机制,包括其工作原理、应用场景以及基本的使用示例。同时,探讨了dup和dup2函数在重定向标准输入输出时的作用,展示了如何将标准输出连接到网络连接,实现数据的发送。通过这些概念和实例,读者可以更好地理解进程通信和文件描述符管理在实际操作中的运用。
摘要由CSDN通过智能技术生成

进程间通信实例

🌰管道
#include <unistd.h>
int pipe(int fd[2]);

//fd[0]是管道的读端,fd[1]是管道的写端,fd[1]的输出就是fd[0]输入
  • 管道其实就是 内核中的一串缓存,往缓存中写&读实现进程通信,传输的是字节流

  • 当然在一个进程内管道作用不是很大,主要发挥作用的场景就是多进程

  • 我们可以通过fork创建子进程, 创建的子进程会复制父进程的文件描述符,那么两个进程就都有fd[0] & fd[1]了,那么就能往缓存中写(write),从缓存中读取(read)

  • 如果用read读取一个空管道,read就会被阻塞直到管道中有数据,write也是一样的

  • 如果fd[1]的引用计数为零,也就是没有写端了,再用read读就返回0(End Of File),如果fd[0]引用计数为零,没有读端了,再用write就会引发SIGPIPE信号。 关于信号的书建议看CSAPP,Lab可以看这里

  • 我们说管道是一个缓存,肯定要有容量的,

基本的管道应用实例

图片来源于小林图解系统

请添加图片描述

#include "csapp.c"
int main()
{
  int n, fd[2];
  pid_t pid;
  char line[1024];
  
  if (pipe(fd) < 0) {						//绑定好管道
    printf("pipe error");
  }
  
  if ((pid = fork()) < 0) {
    printf("fork error");
  }else if (pid > 0) {
    close(fd[0]);								//关掉读端
    write(fd[1], "hello world\n", 12);
  }else {
    close(fd[1]);								//关掉写端
    n = read(fd[0], line, 1024);//从管道内读->line
    write(STDOUT_FILENO, line, n);//将line中的打印(标准输出)
  }
  exit(0);
  
}
🌰dup函数

有时候我们需要将标准输入重定向到一个文件,或者将标准输出重定向到网络连接

太骚了这操作

#include <unistd.h>

int dup(int fd);		//创建新描述符,新的与旧的fd共享同一个文件表项(也就是指向一个文件)
int dup2(int fd1, int fd2);//同dup差不多,返回第一个不小于fd2的整数

我们知道文件描述符号都是整数,因为有这一层抽象我们很轻松的描述文件

  1. 标准输入 0
  2. 标准输出 1
  3. 标准错误 2

使用样例

假设我们创建了一个Server
  //
  
  。。。。。。
  
  //
  
  int connfd = accept(sock, (struct sockaddr *)&client, &client_addrlength);
	//创建了同Client的socket连接了

	close(STDOUT_FILENO);			//关闭标准输出 :1
	dup(connfd);							//使用系统最小可用描述符,那就是1了,那么就将socket同标准输出绑定了
	printf("abcdefg\n");			//我们在标准输出输出的内容就会发送到client对应的socket
	close (connfd);

//...

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值