【Linux】进程间通信(IPC)之信号量详解与测试用例

本文介绍了Linux系统中的进程间通信(IPC)机制,重点关注信号量的概念、工作原理及其在进程同步与互斥中的作用。通过讨论原子操作、临界资源等背景知识,详细阐述了信号量的创建、操作函数如semget、semctl、semop的使用,并通过代码示例展示了如何使用信号量控制临界区,确保多个进程有序访问共享资源。
摘要由CSDN通过智能技术生成

学习环境centos6.5 Linux内核2.6


进程间通信概述

1. 进程通信机制

一般情况下,系统中运行着大量的进程,而每个进程之间并不是相互独立的,有些进程之间经常需要互相传递消息。但是每个进程在系统中都有自己的地址空间,操作系统通过页表和实际物理内存所关联,不允许其他进程随意进入。因此,就必须有一种机制既能保证进程之间的通信,又能保证系统的安全,即进程间通信机制——I P C (Inter_Process Communication)

Linux中的内存空间分为系统空间用户空间。在系统空间中,由于各个线程的地址空间都是共享的,即一个线程能够随意访问kernel中的任意地址,所以无需进程通信机制的保护。而在用户空间中,每个进程都有自己的地址空间,一个进程为了与其他进程通信,必须陷入到有足够权限访问其他进程空间的kernel中,从而与其他进程进行通信。在Linux中支持System V 进程通信的手段有三种:消息队列(Message queue)、信号量(Semaphore)、共享内存(Shared memory)。

2. 进程通信对象标示符和键

在kernel中,对每一类I P C 对象,都由一个非负整数来索引。为了识别并唯一标识各个进程通信的对象,需要一个标识符(即IPC标示符)来标识各个通信对象。而为了获取一个独一无二的通信对象,必须使用(可使用ftok( )函数生成,返回值key)。这里的键是用来定位I P C 对象的标识符的。


背景知识

1. 原子操作(atomic operation)

原子操作意为不可被中断的一个或一系列操作,也可以理解为就是一件事情要么做了,要么没做。而原子操作的实现,一般是依靠硬件来实现的。

2. 同步与互斥

同步:在访问资源的时候,以某种特定顺序的方式去访问资源
互斥:一个资源每次只能被一个进程所访问。

同步与互斥是保证在高效率运行的同时,可以正确运行。大部分情况下同步是在互斥的基础上进行的。
3. 临界资源

不同进程能够看到的一份公共的资源(如:打印机,磁带机等),且一次仅允许一个进程使用的资源称为临界资源

4. 临界区

临界区是一段代码,在这段代码中进程将访问临界资源(例如:公用的设备或是存储器),当有进程进入临界区时,其他进程必须等待,有一些同步的机制必须在临界区段的进入点和离开点实现,确保这些共用资源被互斥所获得。

5. 相关命令
  • ipcs -s 显示已存在的信号量
  • ipcrm -s 删除指定信号量

注意:有时候因为权限问题需要在root下查看与删除。


什么是信号量(Semaphore)

信号量(Semaphore)可以被看做是一种具有原子操作的计数器,它控制多个进程对共享资源的访问,通常描述临界资源当中,临界资源的数目,常常被当做(lock)来使用,防止一个进程访问另外一个进程正在使用的资源。

信号量本身不具有数据交换的功能,而是控制其他资源来实现进程间通信,在此过程中负责数据操作操作的互斥同步等功能。

简言之:信号量的主要目的是为了保护临界资源。
1. 为什么要使用信号量

为了防止出现因多个进程同时访问一个共享资源而引发的问题,我们需要一种方法,可以通过生成并使用令牌来授权,在任一时刻只能有一个执行流访问代码的临界区域。而信号量就可以提供这样的一种访问机制,让一个临界区同一时刻只有一个执行流在访问它。

2. 信号量的工作原理
  1. 测试控制该资源的信号量。

  2. 若此信号量的值为正,则进程可以使用该资源。进程将信号量值减1,,表示一个资源被使用。

  3. 若此信号量的值为0,则进程进入休眠状态,直至信号量值大于0,进程被唤醒,从新进入第1步。

  4. 当进程不再使用由一个信号控制的共享资源时,该信号量值增1,如果有进程正在休眠等待该信号量,则会被唤醒。

为了正确地实现信号量,信号量的操作应是原子操作,所以信号量通常是在内核中实现的。
3. Linux的信号量机制
  1. 在System V中信号量并非是单个非负值,而必须将信号量定义为含有一个或多个信号量值的集合。当创建一个信号量时,要指定该集合中信号量值的数量。

  2. 创建信号量(semget)和对信号量赋初值(semctl)分开进行,这是一个弱点,因为不能原子地创建一个信号量集合,并且对该集合中各个信号量赋初值。

  3. 即使没有进程在使用I P C资源,它们仍然是存在的,要时刻防止资源被锁定,避免程序在异常情况下结束时没有解锁资源,可以使用关键字(SEM_UNDO )在退出时恢复信号量值为初始值。


相关函数

1、ftok函数

#include <sys/ipc.h>
#include <sys/types.h>
key_t ftok(const char* path, int id);
  • ftok 函数把一个已存在的路径名和一个整数标识转换成一个key_t值,即IPC关键字

  • path 参数就是你指定的文件名(已经存在的文件名),

  • 16
    点赞
  • 50
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值