Linux下多进程间sem的原理和应用 (linux 多进程间sem)
Linux操作系统是一个非常强大的操作系统,它具有非常多的优秀特性和功能。其中,多进程间sem是Linux操作系统的一个重要功能。本文将讨论。
一、sem的定义
sem是LINUX内核中的一种基本信号量,用于进程之间进行同步和互斥的工具。Linux操作系统中用信号量来实现进程间的同步互斥,sem是一种抽象数据类型,表示一组计数器,使用时通过系统调用操作sem,它提供了两种基本操作:P(sv)和V(sv),用于请求和释放资源、锁定和解锁。
二、sem的组成
期中,sem定义如下:
struct sem{
int semval; //semaphore value
int sempid; //PID of the last process that performed a semaphore
key_t semkey; //unique key by which a semaphore is referred
};
sem由下列5个部分组成:
1、semaphore value,代表着信号量的值,表示当前可用的资源的数量;
2、last process semaphore pid,最近一次操作信号量的进程的pid,是原子变量,用以保证多个进程访问sem的正确性;
3、unique key,唯一标识sem的符号名;
4、adjustment,sem的调整量,P操作的参数;
5、wt queue,信号量的等待队列,当信号量未满足P操作要求时,要挂起在等待队列上,V操作释放资源后会唤醒等待在等待队列上的进程。
三、sem的使用
在Linux中,可以通过semget()函数获取信号量,它的定义如下:
#include
#include
#include
typedef int semid_t;
extern semid_t semget(key_t key, int num, int flags);
主要有以下参数:
key:标识着信号量的关键字,可以唯一标志一个信号量;
num:表示要创建的信号量的数目;
flags:是一个选项参数,可以指定创建新的信号量,还是获取已经存在的信号量。
通过semget()函数获取到信号量的标志符后,可以使用semctl()系统调用函数对信号量进行操作,semctl()的定义如下:
extern int semctl(int semid, int num, int cmd,union semun arg);
其中,参数semid是由semget()函数返回的信号量标志符,参数cmd是要执行的操作,参数arg是一个共用体类型的指针,它根据cmd来进行不同的操作。semctl()函数的主要操作如下:
1、SETVAL:用来初始化信号量的值;
2、GETVAL:用来获取信号量的值;
3、IPC_RMID:用来删除信号量。
由于sem存在于内核中,操作sem的系统调用影响效率,因此,针对不同应用场景可通过不同的操作模式尽量减小对sem的操作。
四、sem在进程间同步互斥中的应用
1、互斥访问共享资源
在进程间共享同一资源时,要保证该资源不会被多个进程同时访问,可以通过P(sv)和V(sv)操作来实现。
while(1){
P(sem_id);
if(共享资源_空闲){
访问共享资源;
V(sem_id);
break;
}
V(sem_id);
}
2、进程间并发控制
进程间并发控制是指多个进程都对同一资源进行处理时,它们相互合作、竞争,互相影响。通过设置信号量,可实现对进程间的并发进行控制。
3、防止死锁
死锁是指两个或多个进程在执行过程中,因争夺资源而造成一种互相等待的现象,若无外力作用,将无法继续执行下去。当进程需要访问多个资源时,通过设置信号量,就可以在访问一个资源后,才能通过P(sv)访问下一个资源,防止死锁的发生。