`
king_tt
  • 浏览: 2232201 次
  • 性别: Icon_minigender_1
  • 来自: 深圳
社区版块
存档分类
最新评论

Linux进程间通信(六)---信号量通信之semget()、semctl()、semop()及其基础实验

阅读更多

这个信号量理解起来是有点不容易啊,我看书看了好几遍才知道怎么回事。在讲这一节信号量之前,我还是想先说几个小知识点,这也是我在学习完后最终理解的“精华”,哈哈!

信号量是干啥的?

信号量就是用来解决进程间的同步与互斥问题的一种进程间通信机制。

同步与互斥的通俗理解

这两个名词咱们从字面上就能理解。举个例子吧,在创建子进程时,你是怎么保证父子进程执行的先后顺序呢?我在以前的时候是通过sleep()函数来实现的,比如我想让子进程先运行再让父进程运行,那么我就在父进程的程序中加一个sleep()函数,让父进程先睡眠,这样子就能先执行子进程了。有的时候咱们事先无法知道父进程和子进程哪一个先执行,但是要向我那样使用sleep()函数,只能保证先执行子进程,但是不能保证子进程执行完后再执行父进程,这样说能理解吧。所以如果我们想要子进程完全执行完后再执行父进程,就可以利用信号量来解决它们之间的同步问题。还不理解也没关系,我会在后面的实验中再结合实际讲。再举个更通俗的例子,一条食品生产线上,假设A、B共同完成一个食品的包装任务,A负责将食品放到盒子里,B和C负责将盒子打包。必须得是A先装食品B再打包吧,要是B不按规则先打包,那A还装啥,所以就需要一种机制方法保证A先进行B再进行,“信号量”就是这种机制方法,AB之间的关系就是同步关系;再假设打包要用到刀子,而车间就有一把刀子,这时候B和C就构成了互斥关系。

信号量与信号的区别

不瞒你说,我刚开始学的时候所理解的就是“信号量是很多个信号”,当然这是错误的哈!光从英语上看就不一样:信号量是 Semaphore,而信号是 Signal 。其实,信号和信号量是不同的。它们虽然都可以实现同步和互斥,但是前者是使用信号处理器来进行的,而后者是使用P,V操作来实现的。(PV操作后边有讲)

好了,进入正题。

信号量概述

在多任务操作系统环境下,多个进程会同时运行,并且一些进程间可能会存在一定的关联。多个进程可能为了完成同一个任务相互协作,这就形成了进程间的同步关系。而且在不同进程间,为了争夺有限的系统资源(硬件或软件资源)会进入竞争状态,这就是进程间的互斥关系。

进程间的互斥关系与同步关系存在的根源在于临界资源。临界资源是在同一时刻只允许有限个(通常只有一个)进程可以访问(读)或修改(写)的资源,通常包括硬件资源(处理器、内存、存储器及其它外围设备等)和软件资源(共享代码段、共享结构和变量等)。访问临界资源的代码叫做临界区,临界区本身也会称为临界资源。

信号量是用来解决进程间的同步与互斥问题的一种进程间通信机制,包括一个称为信号量的变量和在该信号量下等待资源的进程等待队列,以及对信号量进行的两个原子操作(P/V操作)。其中,信号量对应于某一种资源,取一个非负的整形值。信号量值(常用sem_id表示)指的是当前可用的该资源的数量,若等于0则意味着目前没有可用的资源。

PV原子操作(很重要的)

PV原子操作的具体定义如下:(好好理解,很重要的啊)

● P操作:如果有可用的资源(信号量值>0),则此操作所在的进程占用一个资源(此时信号量值减1,进入临界区代码);如果没有可用的资源(信号量值=0),则此操作所在的进程被阻塞直到系统将资源分配给该进程(进入等待队列,一直等到资源轮到该进程)。

● V操作:如果在该信号量的等待队列中有进程在等待资源,则唤醒一个阻塞进程;如果没有进程等待它,则释放一个资源(即信号量值加1)。

常见的使用信号量访问临界区的伪代码如下图1:

图1中的非临界区和临界区在咱们这里就是代码,具体这张图的理解还要结合着后面的实验才能理解。

最简单的信号量只能取0和1值,这种信号量叫做二维信号量,在本节中,主要讨论二维信号量。二维信号量学好了,比较容易扩展到使用多维信号量的情况。

信号量编程

函数说明

在Linux系统中,使用信号量通常分为以下4个步骤:

① 创建信号量或获得在系统中已存在的信号量,此时需要调用 semget() 函数。不同进程通过使用同一个信号量键值来获得同一个信号量

② 初始化信号量,此时使用 semctl() 函数的SETVAL操作。当使用二维信号量时,通常将信号量初始化为1。

③ 进行信号量的PV操作,此时,调用 semop()函数。这一步是实现进程间的同步和互斥的核心工作部分。

④ 如果不需要信号量,则从系统中删除它,此时使用semctl()函数的 IPC_RMID操作。需要注意的是,在程序中不应该出现对已经被删除的信号量的操作。

函数格式

表2 semctl()函数

基础实验1

这两个实验主要是练习熟悉一下信号量的概念和基本用法,首先,我先在实验1的代码中不添加与信号量相关的代码,观察运行结果,实验代码如下

simple_fork.c文件点此下载

编译运行结果如下

这个运行结果是有点意思哈,由结果可以看到父进程先结束,然后子进程结束,但是我本意不是这样啊,我想让子进程先执行,父进程再执行,也就是父进程等待子进程结束。下面咱们就用信号量来实现它。

基础实验2

本实验使用信号量来解决上面实验1的多进程间存在的同步问题,完成的功能是使父进程等待子进程结束。因为信号量相关的函数调用接口比较复杂,咱们将它们封装成二维单个信号量的基本函数,分别为信号量初始化函数(或者信号量赋值函数)init_sem()、P操作函数sem_p()、V操作函数sem_v()及删除信号量函数 del_sem()等,具体实验代码如下

sem_fork.c文件点此下载




编译运行结果如下

这样通过信号量就保证了它们之间的同步问题

实验分析

下面再进一步结合实验结果重点理解一下 P/V操作,下面再贴出来图1

由实验2的第47~49行可以看出,47行的 P操作和49行的 V操作决定了48行的代码为图1中的临界区(资源R)。

程序执行流程就是,先将信号量值初始化为0(第31行),假设程序先执行父进程,通过前边讲的P操作的特点可知,由于信号量值为0,该进程被阻塞,也就是转而去执行子进程,由V操作可知,执行完子进程后,由于信号量的等待队列中有进程(这里是父进程)在等待资源,则唤醒一个阻塞进程(这里是父进程)。

如需转载:请注明出处:http://blog.csdn.net/mybelief321/article/details/9086151

分享到:
评论

相关推荐

    使用共享内存及信号量实现进程间通信例子

    `semget`用于创建信号量集,`semop`执行信号量操作(如P(等待)和V(释放)操作),`semctl`用于管理信号量集,如初始化或删除。 在实际应用中,信号量常与共享内存结合使用,确保对共享内存的访问是同步的。例如...

    linux进程间通信

    信号量由`semget()`、`semop()`和`semctl()`等系统调用来创建、操作和控制信号量集。 #### 6. 套接字 套接字的创建、绑定、监听、接受连接和发送/接收数据等操作分别由`socket()`、`bind()`、`listen()`、`accept...

    linux进程间通信消息队列信号量共享内存等.pptx

    2. **System V信号量**:利用`<sys/sem.h>`头文件的`semget`, `semctl`, 和 `semop`函数。信号量主要用于进程间的同步,防止多个进程同时访问共享资源,实现互斥。 3. **System V共享内存**:通过`<sys/shm.h>`...

    Linux-进程间通信

    主要函数有`semget`(创建)、`semop`(操作)和`semctl`(设置属性)。 4. **共享内存**:共享内存允许进程直接访问同一块内存区域,提供高效的数据交换。但由于可能存在数据竞争问题,通常与信号量结合使用以确保...

    Linux下C语言编程--进程通信、消息管理

    本文将详细介绍Linux环境下C语言编程中的几种进程通信方法,包括POSIX无名信号量、System V信号量、System V消息队列以及System V共享内存。 #### 1. POSIX无名信号量 ##### 理论基础 信号量是一种用于控制多个...

    进程间通信sample

    在这个“进程间通信sample”项目中,开发者使用了Linux系统下的信号量(Semaphore)来实现进程间的同步与互斥,从而确保对共享资源的正确访问。 信号量是一种同步原语,它是一个计数器,可以用来控制多个进程对共享...

    深刻理解Linux进程间通信(IPC)-详解.pdf

    semget(), semop(), semctl()是System V信号量的调用,而sem_init(), sem_wait(), sem_post()和sem_destroy()是POSIX信号量的调用。 在探讨完以上基本的IPC机制之后,我们注意到内容中还提到了一些关于系统版本和...

    linux进程通信

    ### Linux进程间通信——信号量详解 #### 一、引言 在Linux系统中,进程间的通信机制是实现多进程程序的关键技术之一。进程间通信(Inter-Process Communication,IPC)使得不同进程能够共享数据、协调操作顺序以及...

    浅谈Linux进程间通信方式及优缺点

    Linux提供了semget、semop和semctl等函数,用于创建、操作和控制信号量。 信号(Signal)是另一种通信方式,它更像一种异步通知机制,用于告知接收进程某个特定事件的发生。信号传递的信息量有限,但响应速度快,...

    详解Linux进程间通信——使用信号量

    ### 详解Linux进程间通信——使用信号量 #### 一、什么是信号量 信号量是一种常用的同步机制,用于解决多进程或线程并发访问共享资源时可能出现的竞争条件问题。在多进程环境中,当多个进程尝试同时访问同一个共享...

    进程间通信方式

    本文将详细介绍几种常见的进程间通信方式,包括管道、信号、共享内存、消息队列、信号量以及套接字(socket)等。 #### 二、进程间通信的重要性 进程间通信是多进程环境中必不可少的一项技术。通过IPC机制,进程可以...

    操作系统linux实验五

    通过本次实验,学生能够熟悉信号量的基本概念及其在多线程编程中的作用,并学会如何在实际编程中正确使用信号量来解决进程间通信问题。 #### 实验目的 - 掌握Linux环境下信号量的使用方法。 - 学习Linux中信号量...

    进程间通信

    Linux下的进程通信手段主要继承自UNIX系统,包括了管道、有名管道、信号、消息队列、共享内存、信号量和套接字等多种方式。其中,System V IPC提供了消息队列、信号量和共享内存等机制,主要用于单个计算机内的进程...

    Linux信号量1

    为了解决这个问题,Linux提供了信号量机制,这是一种同步工具,用于协调进程间的访问控制。 信号量是一个共享变量,可以理解为一个计数器,用于管理对共享资源的访问权限。它可以防止多个进程同时访问同一资源,...

    进程通信之信号量.zip

    本文将深入探讨“进程通信之信号量”的概念,特别是在Linux环境下的实现。我们将通过分析名为"seml.c"的源代码来理解这一关键机制。 信号量(Semaphore)是一种同步原语,它在多进程环境下用于控制对共享资源的访问...

    Linux下C语言编程——进程通信

    本篇主要讨论Linux下的几种进程通信机制,包括POSIX无名信号量、System V信号量、System V消息队列以及System V共享内存。 1. **POSIX 无名信号量** POSIX无名信号量是用于同步和保护共享资源的一种机制。信号量的...

    linux信号量专题编程笔记.docx

    - **同步**:在多进程通信中,通过信号量控制生产者和消费者的同步,确保数据的正确传递。 综上所述,Linux信号量是解决并发控制问题的重要手段,通过合理的使用信号量,可以有效地避免竞争条件,实现进程间的同步...

    Sem.rar_linux sem_linux sem.c_信号量

    通过这个示例,你可以深入理解System V信号量的工作原理,并将其应用到实际的多进程项目中,以实现高效且安全的进程间通信。对于任何涉及并发编程和资源管理的Linux开发者来说,掌握这一技能都是至关重要的。

    linux下多值信号量的操作探讨.pdf

    通过以上介绍,我们可以理解 Linux 下多值信号量的操作机制及其在进程间通信中的作用。在实际系统开发中,掌握正确的信号量操作方法能有效提高系统的并发性能和稳定性。参考文献和专业指导可以帮助开发者深入理解并...

Global site tag (gtag.js) - Google Analytics