linux进程间通信之信号量

注意请不要把它与之前所说的信号混淆起来,信号与信号量是不同的两种事物。

摘要

本文旨在深入探讨Linux进程间通信中的信号量机制,包括其工作原理、系统调用接口以及实际应用场景。通过理论分析和示例代码的解读,本文将帮助读者更好地理解信号量在多进程环境中的作用和应用。

一.信号量的简介

在Linux操作系统中,进程间通信(IPC)是一种非常重要的技术,它允许不同的进程之间共享信息和数据。信号量是进程间通信的一种方式,它用于控制多个进程对共享资源的访问。

信号量是一个计数器,它可以被视为一个在进程之间共享的变量。通过使用信号量,一个进程可以等待一个资源被释放,或者通知其他进程一个资源已经可用。
举个例子,就是两个进程共享信号量 sv ,一旦其中一个进程执行了 P(sv) 操作,它将得到信号量,并可 以进入临界区,使 sv 减 1 。而第二个进程将被阻止进入临界区,因为当它试图执行 P(sv) 时, sv 为 0 ,它会 被挂起以等待第一个进程离开临界区域并执行 V(sv) 释放信号量,这时第二个进程就可以恢复执行。

二.信号量工作原理与步骤

信号量是一个计数器,可以看作是在进程之间共享的变量。它主要用于解决多个进程对共享资源的访问冲突问题。当一个进程需要访问共享资源时,它会首先检查信号量的值。如果信号量的值为正,则该进程可以继续执行;如果信号量的值为0,则该进程会被阻塞,直到其他进程释放资源并增加信号量的值。
使用 System V 信号灯的步骤如下:

  1. 使用 semget() 创建或打开一个信号灯集。
  2. 使用 semctl() 初始化信号灯集,。
  3. 使用 semop() 操作信号灯值,即进行 P/V 操作。
    P 操作:申请资源,申清完后信号灯值 -1 ;
    V 操作:释放资源,释放资源后信号灯值 +1 ;

三.系统调用接口

信号量是一个特殊的变量,程序对其访问都是原子操作,且只允许对它进行等待(即 P(信号变量))和发送(即 V(信号变量))信息操作。我们通常通过信号来解决多个进程对同一资源的访问竞争的问题,使在任一 时刻只能有一个执行线程访问代码的临界区域,也可以说它是协调进程间的对同一资源的访问权,也就是用于同步进程的。

在Linux中,使用信号量需要进行一系列系统调用。以下是几个常用的系统调用接口:

1.sem_init

用于初始化一个信号量。它接受三个参数:信号量对象的键值、信号量的初始值和共享内存的权限标志。

2.semop

用于对信号量进行操作,包括锁定和解锁。它接受三个参数:信号量对象的键值、指向sembuf结构体的指针和操作的个数。

3.sem_wait

用于锁定信号量。它将信号量的值减1,如果信号量的值为负,则该进程会被阻塞。

4.sem_post

用于解锁信号量。它将信号量的值加1,如果信号量的值为正,则继续等待的进程将被唤醒。

5.sem_destroy

用于销毁一个信号量。它接受一个参数:信号量对象的键值。

四.实验代码

指定哪个进程运行,可以使用进程间通信的知识,或者使用信号量,这里以使用信号量为例:

cs 复制代码
#include <stdio.h>  
#include <stdlib.h>  
#include <unistd.h>  
#include <sys/ipc.h>  
#include <sys/sem.h>  
  
#define SEMKEY 123456 // 信号量键  
  
int main() {  
    int semid; // 信号量标识符  
    struct sembuf sembuf_lock = {0, -1, SEM_UNDO}; // 用于锁定信号量的结构体  
    struct sembuf sembuf_unlock = {0, 1, SEM_UNDO}; // 用于解锁信号量的结构体  
  
    // 创建信号量,初始值为1  
    if ((semid = sem_init(SEMKEY, 0, 1)) < 0) {  
        perror("sem_init");  
        exit(EXIT_FAILURE);  
    }  
  
    // 创建子进程  
    pid_t pid = fork();  
    if (pid < 0) {  
        perror("fork");  
        exit(EXIT_FAILURE);  
    } else if (pid == 0) { // 子进程  
    printf("Child process is running.\n");  
    // 锁定信号量,等待资源可用
    if (semop(semid, &sembuf_lock, 1) < 0) {  
            perror("semop");  
            exit(EXIT_FAILURE);  
        }  
        printf("Child process got the resource.\n");  
        // 使用资源,模拟执行一段时间  
        sleep(2);  
        // 解锁信号量,释放资源  
        if (semop(semid, &sembuf_unlock, 1) < 0) {  
            perror("semop");  
            exit(EXIT_FAILURE);  
        }  
        printf("Child process finished using the resource.\n");  
        } 
        else { // 父进程  
        printf("Parent process is running.\n");  
        // 等待子进程锁定信号量  
        sleep(1);  
        // 锁定信号量,尝试获取资源,等待子进程释放资源  
        if (semop(semid, &sembuf_lock, 1) < 0) {  
            perror("semop");  
            exit(EXIT_FAILURE);  
        }  
        printf("Parent process got the resource.\n");  
        // 使用资源,模拟执行一段时间  
        sleep(2);  
        // 解锁信号量,释放资源  
        if (semop(semid, &sembuf_unlock, 1) < 0) {  
            perror("semop");  
            exit(EXIT_FAILURE);  
        }  
        printf("Parent process finished using the resource.\n");  
    }  
  
    // 销毁信号量  
    if (sem_destroy(semid) < 0) {  
        perror("sem_destroy");  
        exit(EXIT_FAILURE);  
    }  
    return 0;  
}

五、结论

通过本文对Linux进程间通信之信号量的深入剖析及示例代码的讲解,可以得出以下结论:信号量是一种有效的进程间同步和协调机制,能够解决多个进程对共享资源的访问冲突问题。通过系统调用接口,我们可以创建、操作和销毁信号量。在示例代码中,我们展示了如何使用信号量实现进程间的同步和协调,确保在同一时间只有一个进程使用共享资源,从而避免了竞争条件和数据不一致的问题。总之,信号量是Linux进程间通信中不可或缺的一部分,对于多进程应用程序的开发具有重要意义。

相关推荐
Cachel wood5 分钟前
python round四舍五入和decimal库精确四舍五入
java·linux·前端·数据库·vue.js·python·前端框架
Youkiup13 分钟前
【linux 常用命令】
linux·运维·服务器
qq_2975046117 分钟前
【解决】Linux更新系统内核后Nvidia-smi has failed...
linux·运维·服务器
_oP_i22 分钟前
.NET Core 项目配置到 Jenkins
运维·jenkins·.netcore
weixin_4373982130 分钟前
Linux扩展——shell编程
linux·运维·服务器·bash
小燚~32 分钟前
ubuntu开机进入initramfs状态
linux·运维·ubuntu
小林熬夜学编程39 分钟前
【Linux网络编程】第十四弹---构建功能丰富的HTTP服务器:从状态码处理到服务函数扩展
linux·运维·服务器·c语言·网络·c++·http
炫彩@之星43 分钟前
Windows和Linux安全配置和加固
linux·windows·安全·系统安全配置和加固
上海运维Q先生44 分钟前
面试题整理15----K8s常见的网络插件有哪些
运维·网络·kubernetes
hhhhhhh_hhhhhh_1 小时前
ubuntu18.04连接不上网络问题
linux·运维·ubuntu