System V信号量

本文介绍了System V信号量的概述,包括其与资源管理的关系以及与互斥量的区别。详细讲述了创建或打开信号量的函数semget,以及如何使用semop函数操作信号量,强调了信号量在多资源同步中的作用。
摘要由CSDN通过智能技术生成

1. 信号量概述

System V信号量又被称为System V信号量集,信号量的作用和消息队列不太一样,消息队列的作用是进程之间传递消息。而信号量的作用是为了同步多个进程的操作。

一般来说,信号量和某种预先定义的资源相关联的。信号量元素的值,表示与之关联的资源个数。内核会负责维护信号量的值,并确保其值不小于0。

使用最广泛的信号量是二值信号量。对于这种信号量而言,它只有两种合法值:0和1,对应一个可用的资源。若当前有资源可用,则与之对应的二值信号量的值为1;若资源已经被占用,则与之对应的二值信号量的值为0.当前进程申请资源时,如果当前信号量的值为0,那么进程会陷入阻塞,直到有其他进程释放资源,将信号量的值加1才能被唤醒。

从这个角度看,二值信号量和互斥量所起的作用非常类似。那信号量和互斥量有何不同之处呢?

互斥量是用来保护临界区的,所谓临界区,是指同一时间只能容忍一个进程的进入。而信号量是用来管理资源的,资源的个数不一定是1,可能同时存在多个一模一样的资源,因此容忍多个进程同时使用资源。

更重要的区别是,互斥量和信号量解决的问题是不同的,互斥量的关键在于互斥、排他,同一时间只允许一个线程访问临界区。这种严格的互斥,决定了解铃还须系铃人,即加锁进程必然也是解锁进程

而信号量的关键在于资源的多少和有无。申请资源的进程不一定要释放资源,信号量同样可以用于生产者-消费者的场景。在这种场景下,生产者进程只负责增加信号量的值,而消费者进程只负责减少信号的值。彼此之间通过信号的值

System V信号量是一种进程间通信机制,主要用于进程之间的同步和互斥操作。下面是使用System V信号量的基本步骤: 1. 创建或获取一个信号量集:可以通过semget函数创建一个新的信号量集,也可以通过semget函数获取一个已经存在的信号量集。 2. 初始化信号量:可以通过semctl函数设置初始值。 3. 对信号量进行P操作:可以通过semop函数执行P操作,即获取信号量操作。如果信号量的值大于0,则将其减1并返回;否则,阻塞等待。 4. 对信号量进行V操作:可以通过semop函数执行V操作,即释放信号量操作。将信号量的值加1并返回。 5. 删除信号量集:可以通过semctl函数删除信号量集。 注意事项: 1. 在使用信号量前,需要定义一个semun结构体,用于设置信号量集的属性。 2. 在使用信号量时,需要保证所有进程都能够访问到信号量集,可以通过将信号量集的ID保存在共享内存中,或者使用特殊的关键字来访问。 3. 在使用信号量时,需要注意信号量的值的范围,不能超过信号量的最大值。 下面是一个简单的使用System V信号量的示例程序: ```c #include <stdio.h> #include <stdlib.h> #include <unistd.h> #include <sys/types.h> #include <sys/ipc.h> #include <sys/sem.h> union semun { int val; struct semid_ds *buf; unsigned short *array; }; int main() { int semid; union semun arg; struct sembuf sb; // 创建信号量集 semid = semget(IPC_PRIVATE, 1, IPC_CREAT | 0666); if (semid == -1) { perror("semget"); exit(EXIT_FAILURE); } // 初始化信号量 arg.val = 1; if (semctl(semid, 0, SETVAL, arg) == -1) { perror("semctl"); exit(EXIT_FAILURE); } // P操作 sb.sem_num = 0; sb.sem_op = -1; sb.sem_flg = SEM_UNDO; if (semop(semid, &sb, 1) == -1) { perror("semop"); exit(EXIT_FAILURE); } printf("Enter critical section\n"); sleep(5); printf("Leave critical section\n"); // V操作 sb.sem_num = 0; sb.sem_op = 1; sb.sem_flg = SEM_UNDO; if (semop(semid, &sb, 1) == -1) { perror("semop"); exit(EXIT_FAILURE); } // 删除信号量集 if (semctl(semid, 0, IPC_RMID, arg) == -1) { perror("semctl"); exit(EXIT_FAILURE); } exit(EXIT_SUCCESS); } ``` 这个程序创建了一个信号量集,初始化了一个信号量的值为1,然后执行了一个P操作,进入临界区并睡眠5秒钟,然后执行一个V操作,离开临界区,最后删除了信号量集。
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值