【进程同步】使用信号量实现进程同步(附C++实现代码)

本文详细介绍了进程同步的概念,数据竞争问题以及解决方法——信号量。通过PV操作,解释了信号量如何控制进程对共享资源的访问。接着,分别展示了命名信号量和匿名信号量的创建、使用及销毁,并给出了C++代码示例。最后,通过多值信号量的应用场景——停车场模拟,展示了如何处理多个资源的情况。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >


进程同步

进程同时处理同一串数据, 会造成不确定性,比如有多个进程同时对一个文件进行读写,那么读文件的进程无法确定自己读到的数据是否是它本来想要的数据,还是被修改的数据,除此以外,当先读后写时,由于缓冲区没有写入数据,读进程无数据可读,就会因此被阻塞(使用管道通信)。

这种两个或多个进程读写某些共享数据,而最后的结果取决于进程运行的精准时序,称为数据竞争,而这种多个程序可以并发执行,但是由于系统资源有限,程序的执行不是一贯到底的,以不可预知的速度向前推进,这又被称为异步性

这种受访问顺序影响的数据是没有意义的(程序的运行不能有二义性),所以为了能够使得进程有能够有一定的顺序来访问数据,从而引入了同步的概念。

所谓进程同步就是指协调这些完成某个共同任务的并发线程,在某些位置上指定线程的先后执行次序、传递信号或消息

本文将主要讲解如何使用信号量实现进程同步。

信号量基本概念

信号量相当于一个信号灯,在程序实现中往往是一个非负整数。在实际生活中,如火车进站前会看到的信号灯,若灯亮说明火车可以进站,否则不能进站,这里的信号灯就可以看作是信号量,火车看作是进程,能否进站即能否访问资源。

在进程进入一个关键代码段之前,进程必须获取一个信号量;一旦该关键代码段执行完毕了,那么该线程必须释放信号量。其它想进入该关键代码段的进程必须等待直到第一个进程释放信号量。

信号量

  • 作用:控制多进程共享资源的访问(资源有限并且不共享)
  • 本质:任一时刻只能有一个进程访问临界区(代码),数据更新的代码。

PV操作

PV操作即是针对信号量进行的相应操作,PV操作由P操作原语和V操作原语组成(原语是不可中断的过程)。

当进程执行P操作,若信号量大于零(有共享资源),则信号量减一,进程继续执行;若信号量为零,则进程等待。
在这里插入图片描述
当进程执行V操作,若信号量大于零(有共享资源),则信号量加一;若信号量为零,则唤醒等待进程。如下图所示:

在这里插入图片描述

关于信号量的函数

使用信号量的相关函数时需要添加头文件#include <semapore.h>,链接库为pthread

接下来我们具体学习关于信号量的相关函数,根据信号量是否命名分为命名信号量(基于文件实现)和匿名信号量(基于内存)。

命名信号量相关函数

操作 函数定义
创建 sem_t *sem_open(const char *name, int oflag, mode_t mode,unsigned int value)
删除 int sem_unlink(const char *name)
打开 sem_t *sem_open(const char *name, int oflag)
关闭 int sem_close(sem_t *sem)
挂出 int sem_post(sem_t *sem)
等待 int sem_wait(sem_t *sem)
尝试等待 int sem_trywait(sem_t *sem)
获取信号量的值 int sem_getvalue(sem_t *sem, int *sval)

匿名信号量相关函数

操作 函数
初始化 int sem_init (sem_t *sem , int pshared, unsigned int value)
销毁 int sem_destroy(sem_t *sem)
挂出 int sem_post(sem_t *sem)
等待 int sem_wait(sem_t *sem)
尝试等待 int sem_trywait(sem_t *sem)
获取信号量的值 int sem_getvalue(sem_t *sem, int *sval)

信号量的使用

命名信号量

我们首先创建两个进程,具体代码如下:

#include <iostream>
#include <unistd.h>

using namespace std;

int main(){
   
    fork();
    for(int i=0; i<5; i++){
   
        cout << getpid() << ":before"  << endl;
        sleep(1)
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值