首页 > 系统相关 >Unix系统上使用semop函数写一个信号量函数,确保只有一个进程能访问临界资源

Unix系统上使用semop函数写一个信号量函数,确保只有一个进程能访问临界资源

时间:2024-03-26 20:30:44浏览次数:25  
标签:sops perror 函数 临界 信号量 Unix semop include

semop 是 Unix 系统调用,用于操作信号量集。信号量是一种用于保护共享资源或临界区域免受并发访问的同步原语。

以下是一个使用 semop 的简单示例,确保只有一个进程能访问临界资源:

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <fcntl.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/sem.h>

#define SEM_NAME "/my_semaphore"

int main() {
    key_t key;
    int semid;
    struct sembuf sops[1];

    // 创建一个唯一的键
    if ((key = ftok(SEM_NAME, 'R')) == -1) {
        perror("ftok");
        exit(1);
    }

    // 创建信号量集
    if ((semid = semget(key, 1, IPC_CREAT | 0666)) == -1) {
        perror("semget");
        exit(1);
    }

    // 初始化信号量值为1
    if (semctl(semid, 0, SETVAL, 1) == -1) {
        perror("semctl");
        exit(1);
    }

    // P操作:等待信号量变为正数
    sops[0].sem_num = 0;
    sops[0].sem_op = -1; // 等待
    sops[0].sem_flg = SEM_UNDO; // 如果进程被终止,自动撤销操作

    if (semop(semid, sops, 1) == -1) {
        perror("semop");
        exit(1);
    }

    // 临界区域开始
    printf("进程 %d 进入临界区域\n", getpid());
    sleep(5); // 模拟长时间操作
    printf("进程 %d 离开临界区域\n", getpid());
    // 临界区域结束

    // V操作:增加信号量的值
    sops[0].sem_num = 0;
    sops[0].sem_op = 1; // 释放
    sops[0].sem_flg = SEM_UNDO;

    if (semop(semid, sops, 1) == -1) {
        perror("semop");
        exit(1);
    }

    // 删除信号量集
    if (semctl(semid, 0, IPC_RMID) == -1) {
        perror("semctl");
        exit(1);
    }

    return 0;
}

这个示例创建了一个包含一个信号量的信号量集,并初始化其值为1。当一个进程想要进入临界区域时,它会执行 P 操作(也称为等待或减操作),这会减少信号量的值。如果信号量的值变为0或负数,进程将被阻塞,直到其他进程执行 V 操作(也称为信号或增操作)来增加信号量的值。当进程离开临界区域时,它会执行 V 操作,从而允许其他进程进入临界区域。

注意:此代码未考虑并发性和竞态条件。在实际应用中,您可能需要更复杂的同步机制来确保代码的正确性。此外,代码中的 sleep(5) 仅用于模拟长时间操作,实际应用中应根据需要调整。

标签:sops,perror,函数,临界,信号量,Unix,semop,include
From: https://blog.csdn.net/slty_123/article/details/137056633

相关文章

  • 《深入理解计算机系统》学习(4):过程(如函数)和栈存储
    目录过程1运行时栈2转移控制3数据传送4栈上局部存储过程过程中是软件中一种很重要的抽象,提供了一种封装代码的方式,用一组指定的参数和一个可选的返回值实现了某种功能。然后,可以在程序的不同的地方使用这个功能。设计良好的软件用过程作为抽象机制,隐藏某个行为......
  • C++的format函数
    C++20引入了<format>库,它提供了类似于Python的格式化字符串的功能。你可以使用std::format函数来格式化字符串。format   格式控制标记  [[fill]align][sign][#][0][wigth][precision][type]下面依次讲解format的格式控制标记的基本用法:1.[[fill]align]这个格式......
  • 05-python函数进阶和文件
    函数函数的多返回值变量间逗号隔开,可以多种类型defhello():return1,True,"hello"x,y,z=hello()函数的传参方式位置参数,根据位置传参defcan1(x,y,z):print(x,y,z)can1(2,4,8)关键字参数,根据k=v传参,可以和位置参数混用,位置参数需要在前defcan2......
  • Oracle数据库入门第三课(函数)
    前面二白讲了一些简单的查询语句,仅仅知道查询语句的语法是不够的,要想实现更多的需求,更重要的是函数的使用,这节课我们简单说一下一些函数的使用。一、函数的分类什么叫做函数?函数就是用来实现某种功能的,提前声明好的代码块分类:•系统函数         ‣单行函数......
  • Python函数式编程自带函数
    一.map函数需求1:num1=[1,2,3,4],我的需求是把num1中的每个元素平方后组成新列表。ret=[]num1=[1,2,3,4]foriinnum1:ret.append(i**2)print(ret)#输出结果:>>>[1,4,9,16]需求2:如果有1万个列表呢,怎么办?思路:如果用for循环,当然功能上是没问题的,但是需要......
  • 【RTE里Rte_DRead函数和Rte_Read函数在代码里的区别】
    前言使用RTE时,常会使用到Rte_DRead和Rte_Read函数,今天以代码视角看看二者的区别。应用层在应用层调用Rte_DRead接口函数读取CAN信号值。read_isSignalA=Rte_DRead_Isignal_isSignalA_Isignal_isSignalA();在应用层调用Rte_Read接口函数读取CAN信号值。Rte_Read......
  • 【C语言】Infiniband驱动__mlx4_init_one函数
    一、注释Linux内核驱动程序中的部分,属于Mellanox网卡驱动mlx4的初始化过程。//Mellanox以太网驱动主程序代码staticint__mlx4_init_one(structpci_dev*pdev,intpci_dev_data,structmlx4_priv*priv){interr;//错误码变量intnvfs[ML......
  • 函数是什么?C++函数详解!
    1、函数的声明和定义在复杂的程序中,如果全部的代码都写在main函数中,main函数体将非常庞大臃肿。把任务分工到其它的函数中,main函数只负责程序的核心流程,具体的任务由其它函数完成。这种思想就是模块化编程。声明和定义函数的语法:返回值的数据类型函数名(参数一的数据类型......
  • Pandas基础之drop函数的使用
    drop方法的用法:drop(labels,axis=0,level=None,inplace=False)        -- axis为0时表示删除行,axis为1时表示删除列参数说明:labels:显示要删除的行或列的标签名axis:axis=0时按行删除,axis=1时按列删除level:代表标签所在的索引级别,一般不使用inplace:值为......
  • C++ std::reverse函数
    函数原型,定义std::reverse定义于头文件 <algorithm>1(1)2template<classBidirIt>3voidreverse(BidirItfirst,BidirItlast);(C++20前)45template<classBidirIt>6constexprvoidreverse(BidirItfirst,BidirItlast);(C++20起)......