乐趣区

关于linux:CC服务器开发进程间通信组件的实现

Linux 内核的五大组件

一个残缺的 Linux 内核个别由五大部分组成,他们别离是内存治理,过程治理,过程间通信,虚构文件系统和网络接口。

一、内存治理

内存治理次要实现的是如何正当无效地治理整个零碎的物理内存,同时疾速响应内核各个子系统对内存调配的申请。Linux 内存治理反对虚拟内存,而多余出的这部分内存就是通过磁盘申请失去的,平时零碎只把以后运行的程序块保留在内存中,其余程序块则保留在磁盘中。在内存紧缺时,内存治理负责在磁盘和内存间替换程序块。

二、过程治理

过程治理次要控制系统过程对 CPU 的拜访。当须要某个过程运行时,由过程调度器依据基于优先级的调度算法启动新的过程。:Linux 反对多任务运行,那么如何在一个单 CPU 上反对多任务呢?这个工作就是由过程调度治理来实现的。在零碎运行时,每个过程都会分得肯定的工夫片,而后过程调度器依据工夫片的不同,抉择每个过程顺次运行,例如当某个过程的工夫片用完后,调度器会抉择一个新的过程持续运行。因为切换的工夫和频率都十分的快,由此用户感觉是多个程序在同时运行,而实际上,CPU 在同一时间内只有一个过程在运行,这一切都是过程调度治理的后果。

过程间通信次要用于管制不同过程之间在用户空间的同步、数据共享和替换。因为不必的用户过程领有不同的过程空间,因而过程间的通信要借助于内核的直达来实现。个别状况下,当一个过程期待硬件操作实现时,会被挂起。当硬件操作实现,过程被复原执行,而协调这个过程的就是过程间的通信机制。

三、过程间通信

过程间通信次要用于管制不同过程之间在用户空间的同步、数据共享和替换。因为不必的用户过程领有不同的过程空间,因而过程间的通信要借助于内核的直达来实现。个别状况下,当一个过程期待硬件操作实现时,会被挂起。当硬件操作实现,过程被复原执行,而协调这个过程的就是过程间的通信机制。

(1)过程间通信的目标

  • 数据传输:一个过程须要将它的数据发送给另一个过程;
  • 资源共享:多个过程之间共享同样的资源;
  • 告诉事件:一个过程须要向另一个或者另一组过程发送音讯,告诉他们产生了某种事件。
  • 过程管制:有些过程须要齐全管制另一个过程的执行,此时管制过程心愿可能拦挡另一个过程的所有陷入和异样,并可能及时晓得它的状态扭转。

(2)过程间通信形式

过程间通信次要分为两大规范:System V 规范和 POSIX 规范。
对于 System V 规范的过程间通信次要有以下几类:
1. 管道
管道实用于过程间的数据传输。实质上管道是操作系统在内核中为过程开拓了一块缓冲区,多个过程通过拜访同一缓冲区进行通信,数据在缓冲区中以读写的形式被不同过程获取和操作。
管道有三大个性:
1. 生命周期随过程;
2. 自带同步与互斥;
3. 提供字节流服务。
管道次要分为匿名管道和命名管道

  • 匿名管道
    后面说了管道是操作系统为过程在内核中调配的一块缓冲区,匿名管道就是指这块缓冲区没有标识符,因而其余过程无奈间接拜访匿名管道,只有相似父子过程这样的具备亲缘关系的过程能力应用匿名管道进行通信(起因是子过程会复制父过程的 PCB,其中包含这块信息)。匿名管道的创立应用如下接口:
int pipe(int fd[2]) 

这个接口的作用是创立一个匿名管道,并向用户返回这个管道的操作句柄,其中参数 fd[2]中 fd[0]用于从管道中读取数据,fd[1]用于从管道中写入数据,如果创立胜利返回 0,创立失败返回 -1.
匿名管道的个性是:
1. 若管道中没有数据,应用读操作会阻塞;

  1. 若管道写满了,应用写操作会阻塞;
  2. 若管道的写端敞开了,读完数据之后不会阻塞而是返回 0;

4. 若管道的读端敞开了,持续写入数据会触发异样,程序退出。
这些个性体现了管道自带同步与互斥。

  • 命名管道
    命名管道和匿名管道相同,命名管道是有标识符的一块缓冲区,并且这个标识符个别是一个可见于文件系统的文件。所以命名管道是一个非凡类型的文件,其余过程能够通过这个标识符找到这块缓冲区,即通过关上同一个管道文件,拜访到同一缓冲区,进而实现过程间通信。
    创立一个命名管道既能够应用 mkfifo filename 命令也能够应用接口,函数接口如下:
int mkfifo(const char* pathname, mode_t mode) 

参数 pathname 是命名管道文件的名称,mode 是文件权限。如果创立胜利返回 0,失败返回 -1.
命名管道的关上个性:
1. 若管道文件以只读的形式关上,会阻塞,直到这个文件被以写的形式关上;
2. 若管道文件以只写的形式关上,会阻塞,直到这个文件被以读的形式关上;
3. 若文件以读写的形式关上,就不会阻塞。
不论是匿名还是命名管道,同查那个对管道进行的数据操作的大小不超过 PIPE_BUF 这个宏的大小,默认是 4KB。

2. 共享内存
共享内存用于过程间的数据共享,是最快的过程间通信。共享内存的创立大略是以下步骤:首先,在物理内存中开拓一块空间,将这块物理内存映射到程序的虚拟地址空间,过程就能够通过虚拟地址来拜访这块内存。多个过程映射到同一物理内存,这样进行通信的形式,不须要进入内核,只须要再共享的内存区进行操作即可。其余形式的通信都是因为内核中的缓冲区,过程在通信的时候会波及内核态和用户态的两次数据拷贝。而共享内存不会所以速度更快。

  • 共享内存的操作流程:
    1. 创立共享内存即开拓具备标识符的物理内存空间;
    2. 将共享内存映射到各个过程的虚拟地址空间;
    3. 间接通过虚拟地址进行对共享内存的操作;
    4. 解除映射;
    5. 开释共享内存。
int shmget(key_t key, int size, int flag)  // 创立一个共享内存

void* shmat(int shmid, void* addr, int flag) // 建设映射

int shmdt(void* shmstart) // 解除映射

int shmctl(int shmid, int cmd, struct shmid_ds* bf) // 操作共享内存
//cmd 参数为 IC_RMID 的时候是删除共享内存 

当删除共享内存的时候,共享内存不会立刻被删除(因为可能造成正在拜访的过程奔溃)而是将 key 批改成 0,示意这块共享内存不会再接管映射链接,当这块共享内存的映射链接为 0 的时候,则主动开释。
须要留神的是共享内存自带没有同步与互斥。
3. 音讯队列
音讯队列用于过程间的数据传输(有标识符)
音讯队列实际上就是内核中的一个优先级队列,多个过程通过向同一个队列中 增加 或者 获取 节点来实现通信。次要是传输一个有类型(优先级)的数据块。
个性:
1. 自带同步与互斥;
2. 生命周期随内核;
3. 数据传输自带优先级。

信号量
信号量用于实现过程间的管制,次要是同步和互斥。
实质:内核中的一个计数器(对资源进行计数) + pcb 期待队列

互斥的实现:通过只有 0 / 1 的计数器,实现对临界资源拜访状态的标记,在拜访临界资源
之前先获取信号量,计数 -1;若计数 <0 则使过程期待(将过程 pcb 退出队列中);否则可
以对临界资源进行拜访(并且在访问期间,曾经将临界资源的状态置为不可拜访状态,因而
可一保障其余过程不会再拜访临界资源。以后过程拜访结束之后,则对计数进行 +1,则唤醒
一个过程(将一个 pcb 出队,置为运行状态)

同步的实现:信号量是一个对资源的计数,能够通过计数判断是否可能获取一个资源进行处
理;若计数小于 0,则示意不能获取(并且对计数进行 -1),须要期待(退出 pcb 队列)。
这时候若其余过程生产一个资源,则会对计数进行 +1,若计数 <= 0,则唤醒一个过程。
(正数示意正在期待过程的数量,如果为正阐明没有过程须要资源)。

【Linux 内核】Linux 内核过程间通信组件的实现(上)
【Linux 内核】Linux 内核过程间通信组件的实现(下)

四、虚构文件系统

Linux 内核中的虚构文件系统用一个通用的文件模型表示了各种不同的文件系统,这个文件模型屏蔽了很多具体文件系统的差别,使 Linux 内核反对很多不同的文件系统,这个文件系统能够分为逻辑文件系统和设施驱动程序:逻辑文件系统指 Linux 所反对的文件系统,例如 ext2、ext3 和 fat 等;设施驱动程序指为每一种硬件控制器所编写的设施驱动程序模块。

五、网络接口

网络接口提供了对各种网络规范的实现和各种网络硬件的反对。网络接口个别分为网络协议和网络驱动程序。网络协议局部负责实现每一种可能的网络传输协定。网络设备驱动程序则次要负责与硬件设施进行通信,每一种可能的网络硬件设施都有相应的设施驱动程序。


退出移动版