C语言用信号量进行pv操作

这篇具有很好参考价值的文章主要介绍了C语言用信号量进行pv操作。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

一、获取信号量

用semget()函数获取信号量,其中semget()函数中所需传的参数如下:

semget(key_t key , int nsems, semflg);

参数解释:

1、其中key可以通过ftok() 函数进行获取,ftok函数所需传入的参数为①文件路径②一个八位的整数

2、nsems是所需创建的信号量的个数,如果只是访问已存在的信号量集合,可以将此参数设置为0。

3、semflg是一个标志参数,用于指定创建或访问信号量集合的方式,常用的标志有:

IPC_CREAT:如果指定的键值对应的信号量集合不存在,则创建一个新的信号量集合。

IPC_EXCL:与IPC_CREAT同时使用,如果指定的键值对应的信号量集合已经存在,则返回错误。

0666:用于指定信号量集合的权限,表示允许所有用户读写信号量集合,这里也可以是填其它权限,如0664等,不一定是0666

具体实现:

int sem_creat(key_t key, int nsems)
{
    int semid = semget(key, nsems, 0664|IPC_CREAT);//创建信号量
    
    if(semid < 0){  //通过返回值判断信号量是否创建成功,小于零则创建失败,打印一下错误信息并退出
        perror("semget");
        exit(0);    
    }
    return semid;
}

二、初始化信号量

用semctl来初始化信号量,其中semctl函数所需传入的参数如下:

int semctl(int semid, int semnum, int cmd, ...)

参数解释: 

1、semid:信号量集合的标识符,通过smget函数获取(也就是上一步获取信号量的时候得到的)。

2、semnum:要操作的信号量在集合中的索引(也就是要初始化哪一个信号量),对于一个信号量集合可以有多个信号量,而semnum指定了要操作的具体信号量

3、cmd:指定要执行的命令,可以是以下几种之一:

①、GETVAL:获取指定信号量的当前值。

②、SETVAL:设置指定信号量的值。

③、IPC_RMID:删除信号量集合。

④、IPC_STAT:获取信号量集合的状态信息。

⑤、IPC_SET:设置信号量集合的状态信息。

⑥、GETALL:获取所有信号量的当前值。

⑦、SETALL:设置所有信号量的值。

4、....:表示可变参数,根据不同的命令有不同的使用方式,需要注意的是。semctl函数的第四个参数arg的具体含义取决于使用命令和使用方式(也就是根据第三个参数来的),对于某些命令,arg是一个整数值,而对于其它命令,arg是一个指向union semun结构体的指针。在使用semctl函数时,需要根据具体的需求和命令来确定如何使用这个参数。

具体实现:

void init_sem(int semid,int semnum,int val)//初始化需要传semid和初始化哪个信号量,还有初始化的值
{
    int ret;
    union semun sem;//这个是根据第三个参数来的,semun联合体中有好多种数据类型
    sem.val = val;
    ret = semctl(semid,semnum,SETVAL,sem);//这里用的是SETVAL,所以要传第四个参数,也就是你要初始化的值
    if(ret < 0)//判断是否初始化成功
    {
        perror("semctl");
        exit(0);
    }
}

注意: union semun联合体(也叫共用体)需要我们自己去实现,大概的样子长这样:

union semun {
    int val;                  // 设置信号量的初始值或获取当前值
    struct semid_ds *buf;     // IPC_STAT 或 IPC_SET 时使用
    unsigned short *array;    // GETALL 或 SETALL 时使用
};

三、进行p操作(加锁操作)

用semop函数来进行加锁操作,semop函数传入的参数如下:

 int semop(int semid, struct sembuf *sops, size_t nsops);

参数解释: 

1、semid:是一个信号量集标识符,用于指定要操作的信号量集。在使用semget函数创建信号量集后,会返回该标识符。

2、sops:是一个指向sembuf结构体数组的指针,每个sembuf结构体表示对一个信号量的操作(也就是通过结构体来设置信号量当前的状态)。

sembuf结构体的定义如下:

struct sembuf {
    unsigned short sem_num;  // 信号量在信号量集中的索引
    short sem_op;            // 信号量的操作
    short sem_flg;           // 操作标志
};

其中

sem_num是要操作的信号量在信号量集中的索引,从0开始计数

sem_op:是对信号量的操作,可以是正整数、负整数或零。

·  正整数表示将信号量的值增加相应的数量。

·  负整数表示将信号量的值减少相应的数量。

·  零表示等待信号量变为零。

 sem_flg是操作标志,用于指定操作的行为,常见的取值有:

  • SEM_UNDO:如果进程退出时仍然持有该信号量,则会自动释放。
  • IPC_NOWAIT:如果无法立即执行操作,则函数会立即返回,并设置错误码为EAGAIN

3、nsops:表示sembuf结构体数组中元素的数量,即要进行操作的信号量的个数。

具体实现:

void sem_p(int semid,int semnum,size_t nsops)
{
    struct sembuf sops;
    sops.sem_num = semnum;//设置要操作哪个信号量
    sops.sem_op = -1;//设置信号量要执行的操作,-1是上锁的操作,锁-1
    sops.sem_flg = SEM_UNDO;//防止死锁‘
    
    int ret = semop(semid,&sops,nsops);
    if(ret < 0)//判断是否执行成功
    {
        perror("semop-p");
        exit(0);
    }    
}

四、进行v操作(解锁操作) 

进行v操作也是用的semop函数,只是传的参数不同,sops.sem_op = 1。

具体实现:

void sem_v(int semnum,size_t nsops)
{
    struct sembuf sops;
    sops.sem_num = semnum;
    sops.sem_op = +1;//与p操作不同的地方
    sops.sem_flg = SEM_UNDO;
    
    int ret = semop(semid,&sops,nsops);
    if(ret < 0)
    {
        perror("semop-v");
        exit(0);
    }
}

五、释放信号量

释放信号量也可以用semctl()函数,只是传的参数有变化文章来源地址https://www.toymoban.com/news/detail-635275.html

具体实现:

void sem_destroy(int semid)
{
    int ret = semctl(semid,-1,IPC_RMID);
    if(ret < 0)
    {
        perror("semctl-rmid");
        exit(0);
    }
}

到了这里,关于C语言用信号量进行pv操作的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • 6.物联网操作系统信号量

    一。信号量的概念与应用 信号量定义 FreeRTOS信号量介绍 FreeRTOS信号量工作原理 1.信号量的定义         多任务环境下使用,用来协调多个任务正确合理使用临界资源。 2.FreeRTOS信号量介绍         Semaphore包括Binary,Count,Mutex;         Mutex包括RecursiveMutex,Mutex。 3.Free

    2024年02月14日
    浏览(37)
  • 【Linux C | 多线程编程】线程同步 | 信号量(无名信号量) 及其使用例子

    😁博客主页😁:🚀https://blog.csdn.net/wkd_007🚀 🤑博客内容🤑:🍭嵌入式开发、Linux、C语言、C++、数据结构、音视频🍭 🤣本文内容🤣:🍭介绍 🍭 😎金句分享😎:🍭你不能选择最好的,但最好的会来选择你——泰戈尔🍭 ⏰发布时间⏰: 本文未经允许,不得转发!!!

    2024年04月26日
    浏览(30)
  • linux(信号量)

    1.回顾信号量的概念 2.认识信号量对应的操作函数 3.认识一个环形队列 4.结合sem+环形队列写生产者消费者模型 --------------------------------------------------------------------------------------------------------------------------------- 1.回顾信号量的概念  每个人想进放映厅看电影,第一件事就是买票

    2024年02月11日
    浏览(34)
  • linux信号量

    通过学习linux的信号量,对linux的信号量进行了编程。

    2024年02月10日
    浏览(35)
  • 【Linux】浅谈信号量

    tips:system V 是一套标准,共享内存,信号量,消息队列属于system V。 进程A和进程B进行通信时,假如进程A向物理内存的共享区写入\\\"Hello World\\\",但是当进程A写入了\\\"Hello\\\"时,进程B就向内存读取了,所以只读取到了\\\"Hello\\\",这就导致进程A想向进程B发送的信息,进程B读取不完整,

    2024年02月05日
    浏览(38)
  • 【Linux】进程间通信 -- 信号量

    信号量是什么? 本质是一个计数器,通常用来表示公共资源中,资源数量多少的问题 公共资源:能被多个进程同时可以访问的资源 访问没有保护的公共资源:数据不一致问题(比如我想写abc123,但是我123还没有写入,就读取了abc,可能数据分开会导致数据无意义) 为什么要

    2024年02月16日
    浏览(39)
  • linux进程间通信(信号量)

    信号量是一个特殊的变量,程序对其访问都是原子操作,且只允许对它进行等待(即 P(信号变量))和发 送(即 V(信号变量))信息操作。最简单的信号量是只能取 0 和 1 的变量,这也是信号量最常见的一种形式, 叫做二进制信号量。而可以取多个正整数的信号量被称为通用信号

    2024年02月07日
    浏览(29)
  • 【Linux篇】第十七篇——信号量

    前言 POSIX信号量 信号量的概念 信号量的工作原理 信号量函数 二元信号量模拟实现互斥功能 基于环形队列的生产消费模型 空间资源和数据资源 生产者和消费者申请和释放资源 必须遵守的两个规则 代码实现 信号量保护环形队列的原理 将可能被多个执行流同时访问的资源叫

    2024年02月06日
    浏览(37)
  • 12.3用信号量进行线程同步——生产者与消费者问题

    1.shell程序设计 2.内存管理 3.链接库 4.文件操作

    2024年02月04日
    浏览(32)
  • linux中互斥锁,自旋锁,条件变量,信号量,与freeRTOS中的消息队列,信号量,互斥量,事件的区别

    对于目前主流的RTOS的任务,大部分都属于并发的线程。 因为MCU上的资源每个任务都是共享的,可以认为是单进程多线程模型。 【freertos】003-任务基础知识 在没有操作系统的时候两个应用程序进行消息传递一般使用全局变量的方式,但是如果在使用操作系统的应用中用全局变

    2024年02月11日
    浏览(33)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包