目录
引言
ipc简介
ipc在kernel的管理机制(简介)
信号量
理解信号量
原子
结论
mmap
消息队列
接口
引言
在复杂的软件系统中,进程间的协调和通信是确保系统高效、稳定运行的关键。System V是一套历史悠久且功能强大的进程间通信(IPC)机制,它为Unix和类Unix操作系统提供了多种通信手段,其中包括信号量和消息队列。这两种机制各自以其独特的方式,为进程间的同步和数据传递提供了可靠的解决方案。本文将引入System V信号量和消息队列的概念,探讨它们在进程同步和通信中的作用,以及它们在现代软件开发中的应用场景和优势。通过深入了解这些经典IPC工具的工作原理和使用方法,开发者能够更好地构建高并发、高可靠性的系统应用。
ipc简介
IPC(Inter-Process Communication,进程间通信)是在多任务操作系统中,不同进程之间进行数据交换和同步的一种机制。在Linux系统中,有多种IPC方法,每种方法都有其特定的用途和优缺点。
以下是一些常见的Linux IPC机制:
管道(Pipes)和命名管道(FIFOs):
无名管道:只允许具有亲缘关系的进程之间通信,如父子进程。
命名管道:也称为FIFO,可以在任意两个进程之间进行通信。
信号(Signals):
信号是一种较为简单的通信方式,用于通知接收进程某个事件已经发生。
消息队列(Message Queues):
消息队列允许一个或多个进程写入或读取数据,这些数据以消息为单位进行传输。
共享内存(Shared Memory):
允许多个进程共享一段内存区域,是最快的IPC方式,但需要同步机制(如信号量)来避免竞态条件。
信号量(Semaphores):
主要用于同步,确保多个进程可以安全地访问共享资源。
套接字(Sockets):
提供了在不同主机上的进程间进行双向通信的能力,支持网络通信。
每种IPC机制都有其适用场景和限制:
管道和命名管道:适合于字节流数据的简单通信。
信号:通常用于通知,而不是传输大量数据。
消息队列:提供了有序、可靠的数据传输,但速度不如共享内存。
共享内存:适用于需要高速数据交换的场景,但需要谨慎处理同步问题。
信号量:用于同步,而不是数据传输。
套接字:适合于分布式系统中的进程间通信。
选择合适的IPC机制取决于具体的应用需求,包括通信的数据量、通信频率、通信的可靠性要求以及通信双方的关系等因素。在使用这些机制时,需要考虑同步、互斥、死锁和竞态条件等问题,以确保数据的一致性和系统的稳定性。
ipc在kernel的管理机制(简介)
每一个systemV的数据结构(信号量、共享内存、消息队列),都有一个shmid_ds的数据结构去描述他的属性,这些被组织在一个队列中,可以通过指针强转解引用去找到perm属性中的key,从而找到特定的数据结构。
信号量
基础知识
这就是因为多个进程共同抢夺唯一当临界资源--显示器。
因为显示器也是一种共享资源,但是没有被设置为临界资源。
理解信号量
我们可以引入一个计数器cnt--,表示申请资源。
核心:先去申请信号量去预订资源
这是因为进程在执行的时候可以在任意时刻被切换。
原子
技术角度:只有一条汇编语句,就是原子的
结论
多个信号量和信号量是几是不同的概念。
mmap
在使用 mmap
处理大文件时,你首先需要映射文件,然后就可以通过访问映射后的内存区域来间接访问文件内容,而不是使用传统的文件读写接口(如 read
、write
、fread
、fwrite
等)。这种方式可以显著提高大文件操作的效率。
#include <sys/mman.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>int main(int argc, char *argv[]) {int fd;void *map;struct stat sb;fd = open(argv[1], O_RDONLY);if (fd == -1) {perror("Error opening file");exit(EXIT_FAILURE);}if (fstat(fd, &sb) == -1) { /* To obtain file size */perror("Error fstat");exit(EXIT_FAILURE);}map = mmap(NULL, sb.st_size, PROT_READ, MAP_PRIVATE, fd, 0);if (map == MAP_FAILED) {perror("Error mmap");exit(EXIT_FAILURE);}// 使用映射的内存区域...if (munmap(map, sb.st_size) == -1) {perror("Error munmap");exit(EXIT_FAILURE);}close(fd);return 0;
}
消息队列
消息队列(Message Queue)是一种进程间通信(IPC)机制,它允许一个或多个进程(生产者)将消息发送到一个队列中,而其他进程(消费者)可以从中读取这些消息。消息队列提供了一种异步的通信方式,即发送消息的进程在发送消息后可以继续执行,不需要等待接收进程确认接收。
以下是消息队列的一些关键特点和解释:
1.消息存储:消息队列由内核维护,它存储了一系列的消息。每个消息通常包含一个类型和数据部分,数据部分可以是任意长度的字节序列。
2. 异步通信:生产者和消费者不需要同时在线。生产者可以在任何时间点将消息放入队列,消费者可以在任何时间点从队列中取出消息.
3.消息顺序:消息队列通常保证消息的顺序,即先入先出(FIFO)。第一个被放入队列的消息将是第一个被取出的消息。
4.系统资源:消息队列是系统资源,通常由操作系统内核管理。它们有唯一的标识符,可以通过这个标识符被进程访问。
5.同步和互斥:内核通常会处理消息队列的同步和互斥问题,确保多个进程可以安全地访问消息队列而不会发生冲突。
6.消息传递模式:
点对点模式:一个消息队列只能由一个消费者接收,即消息从生产者发送到单个消费者
。发布/订阅模式:多个消费者可以订阅同一个消息队列,每个消费者都可以接收到队列中的消息。
消息队列的使用步骤通常包括以下几个阶段:
创建消息队列:在使用消息队列之前,需要创建一个消息队列,并获取其标识符。
发送消息:生产者进程将消息发送到消息队列中。如果队列已满,发送操作可能会阻塞,直到队列中有空间。
接收消息:消费者进程从消息队列中读取消息。如果队列为空,接收操作可能会阻塞,直到队列中有消息。
删除消息队列:当消息队列不再使用时,可以将其删除以释放系统资源。
允许不同的进程向内核发送数据块。
接口
由于是systemV标准,所以接口十分类似共享内存。