腾讯面试:进程通信了解么?

网络 通信技术
怎样实现父进程和子进程通信呢?我那篇讲进程的文章中讲过父进程创建子进程是怎么创建的,大家还记得吗?就是要用 fork。父进程通过 fork 创建子进程,子进程会把父进程的代码复制一份,这样父进程的输入端描述符子进程也复制到了。

[[432787]]

本文转载自微信公众号「CS指南」,作者大白。转载本文请联系CS指南公众号。

中午

一个阳光明媚的中午,大白来到了领导的办公室。

大白:领导,从昨天晚上开始,我牙特别疼,我感觉我得去一趟医院...

领导:好的,你快去吧哈,最近注意身体...

当日下午

腾讯大楼,某会议室内~

大白:面试官您好,我是大白!我虽然刚工作不到一年,但是我有强悍的编程基本功以及有丰富的项目经验......

面试官:行,我大概了解了,接下来我问你点八股...不是,我们好好探讨一些底层原理。

大白:(内心:没问题,我就擅长这个,你没看过我的八股文骚套路系列吗?)好的,面试官!

面试官:先问个简单的,你讲下进程与线程的区别吧!

大白:好的,一个进程里可以包含很多线程!

面试官:没了?

大白:没了呀。

面试官:我对你的面试差不多了,你回去等结...

面试正式开始

大白:别别别,开个玩笑。其实两者区别还挺大的,先从进程讲起,我之前就写过一篇讲 Linux 进程创建 的文章...

面试官:打断一下,你那篇文章我看过,写的还不错。我问点你在文章里没提到的。你了解进程通信吗?

大白:了解呀,主要有以下几种进程通信方式:管道、消息队列、共享内存、信号量、Socket。

面试官:那你平常用过管道的方式进行进程通信吗?

大白:用过呀,经常用。管道有匿名管道和命名管道两种。我下面给您详细介绍下。

先举个例子吧,下面这条 linux 命令就运用了管道。

  1. echo "I'm dabai" | tee a.out 

上面这条命令的具体功能是在 Linux 控制台输出 “ I’m dabai”,并且将输出的信息作为输入传递到 a.out 文件中。可以看出 I 的左边是输入,右边是输出。“|”代表的管道随着命令创建,命令执行完成后也会自动销毁.

另外一种方式就是通过 mkfifo 显示创建命名管道。

  1. mkfifo dabaipipe 

上述命令就创建了一个名叫 “dabaipipe" 的管道。我们可以向管道中写入信息,比如:

  1. echo "hello ! I'm dabai" > dabaipipie 

想要读取管道中的信息,采用下面的命令就可以啦!

  1. cat < dabaipipe 
  2.  
  3. #输出 hello ! I'm dabai 

面试官:呦!还不错,那我问你什么时候该用匿名管道,什么时候该用命名管道。

大白:其实这要从匿名管道的缺点说起。匿名管道有两个缺点,这既是他的缺点也是他的特点。

(1)匿名管道仅支持父进程和子进程间的通信。

(2)匿名管道不支持跨网络的两个进程之间的通信

也正是因为这两个特点,匿名管道所需要的系统开销比命名管道小很多。(匿名管道中的文件不会写到磁盘上,而命名管道中的文件会写到磁盘上)

所以什么时候该用匿名管道,什么时候该用命名管道就很显而易见了。(快夸我)

面试官:等等,你说啥?你说匿名管道仅仅支持父进程和子进程间的通信?那你刚才这条命令 “echo "I'm dabai" | tee a.out”,谁是谁的子进程?

大白:(内心:这面试官果然不讲武德!幸亏我早有准备,就等着你跳坑了,就这个点我能给你讲到面试结束)

是这样的,匿名管道的创建过程很有意思,我给您讲一下,这样就能解答您刚才的问题。

如果要创建匿名管道,我们需要接下来的几步。

1.我们需要创建匿名管道的"管子",其实就是内核中的一段缓存。

2.为了通信,我们需要创建一个进程,然后在进程中会创建两个文件描述符指向管道的两端(一个指向输入端,一个指向输出端)。

这个时候,我们的匿名管道就变成下面这个样子了。进程想要向管道中输入数据那么就通过输入端描述符进行写入操作,想要从管道中取数据就通过输出端描述符进行读取操作。

从上面的图我们也可以看出,根本没有实现进程间通信。那么怎样实现父进程和子进程通信呢?我那篇讲进程的文章中讲过父进程创建子进程是怎么创建的,大家还记得吗?就是要用 fork。父进程通过 fork 创建子进程,子进程会把父进程的代码复制一份,这样父进程的输入端描述符子进程也复制到了。这个时候父进程和子进程都会同时指向管道。

我们再将子进程的输入关闭,父进程的输出关闭,就可以啦!

至于”echo "I'm dabai" | tee a.out “ 这条命令, | 两边并不是父子进程,那他们是怎么完成进程通信的。其实,这两个进程都是通过 shell 进程 fork 出来的。然后两个进程分别就连接到管道的输入和输出端了。再把多余的输入和输出关闭就可以啦。

最后匿名管道的结构图我就不用画了吧?(内心:这面试都一个多小时了,我还回公司蹭免费晚餐和九点下班打车呢)

面试官:要不你还是画一下吧!

大白:那好吧...就是下面这个样子!(内心:你就不急着去吃饭吗?)

面试官:小伙子可以呀,我对你挺满意的,我给你过了。本来还想详细问问你进程通信的其它几种方式,但是我得下班了。你等等下一面的面试官约你面试时间吧!

和面试官加了微信后。看了看时间,还行,还能回趟公司把餐补领了再回家,又是充实的一天。最近把进程通信其他几种方式学一学给下一面面试官讲。

参考资料:

极客时间《趣谈 Linux 操作系统》 链接:http://gk.link/a/10zn1

《Linux系统编程、网络编程》第7章 进程间通信(本机IPC) 链接:https://www.bilibili.com/video/BV1fE411v7Bb

 

JavaGuide 操作系统篇 链接:https://snailclimb.gitee.io/javaguide/#/docs/cs-basics/operating-system/basis

 

责任编辑:武晓燕 来源: CS指南
相关推荐

2019-11-27 10:36:11

进程通信IPC

2023-12-08 13:16:00

CSSJSXStyleX

2017-08-06 00:05:18

进程通信开发

2016-09-26 14:45:46

微服务

2021-05-08 21:26:04

Redismemcachedset

2019-07-09 10:31:51

面试通信进程

2009-12-25 11:22:13

Linux进程技术

2010-01-05 10:00:48

Linux进程间通信

2021-10-18 08:41:20

Redis ACID事务

2009-12-17 11:28:03

Linux系统开机

2010-07-06 17:14:03

网关通信协议

2010-05-14 13:05:57

2010-08-11 12:07:08

腾讯笔试题腾讯笔试题

2022-06-07 07:37:40

线程进程开发

2011-06-22 17:09:50

QT 进程 通信

2011-08-08 15:14:11

PPPOE

2020-11-04 07:17:42

Nodejs通信进程

2021-07-06 21:30:06

Linux进程通信

2020-11-12 18:20:28

接口数据分布式

2019-11-08 14:47:49

TCPIP网络
点赞
收藏

51CTO技术栈公众号