systemV信号量与消息队列

目录

引言

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 处理大文件时,你首先需要映射文件,然后就可以通过访问映射后的内存区域来间接访问文件内容,而不是使用传统的文件读写接口(如 readwritefreadfwrite 等)。这种方式可以显著提高大文件操作的效率。

#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标准,所以接口十分类似共享内存。

IPC 资源必须删除,否则不会自动清除,除非重启,所以 system V IPC 资源的生命周期随内核
注意,除了systemV标准,还有POSIX 标准。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值