进程间通信之信号量篇

首先我们应该知道什么是信号量?
信号量本质上是一个计数器,表示可用资源个数,用于多进程对共享数据对象的访问。信号量并不是让进程间能直接的发送字符串数据,而是通过自身计数器的性质,来完成进程间的同步和互斥。那什么又是进程的同步和互斥呢?
进程互斥:
由于各进程要求共享资源,而且有些资源需要互斥使用,因此各进程间竞争使用这些资源,进程的 这种关系为进程的互斥 系统中某些资源一次只允许一个进程使⽤,称这样的资源为临界资源或互斥资源。 在进程中涉及到互斥资源的程序段叫临界区。
进程同步:
进程同步指的是多个进程需要相互配合共同完成一项任务。
由于信号量只能进行两种操作等待和发送信号,即P(sv)和V(sv),互斥时,P,V在同一个进程中,同步时,P,V在不同进程中,sv为信号量,S>0:S表示可⽤资源的个数 S=0:表⽰无可用资源,⽆等待进程。S<0:|S|表示等待队列中进程个数。
我们对信号量值的操作应为原子操作(即为不可再分) ,原因如下:假设两个进程都要对临界资源进行p操作,则两个进程完全可能同一时间去申请资源,若信号量值为1,减2次就会出问题,正确的做法是把申请资源,使用资源,释放资源变成一个原子操作(即为不可再分),这就意味着,要么(申请资源,使用资源,释放资源)这三个动作都做完了,要么一个没做,于是两个进程在资源的使用上有个先后顺序,这就意味着一个进程完成了原子的p操作后,信号量变为0,另一个进程就要阻塞等待。
信号量结构体伪代码

struct semaphore
 {
    int value;  
    pointer_PCB queue; 
 }

P原语
P(s) 
{    
s.value = s.value--;   
 if (s.value < 0)   
 {  
  该进程状态置为等待状态 
 将该进程的PCB插入相应的等待队列s.queue末尾 
 }
} 
V原语
V(s)
 {   
  s.value = s.value++;   
   if (s.value < =0)   
   {
    唤醒相应等待队列s.queue中等待的一个进程       
    改变其状态为就绪态
    并将其插入就绪队列    
    }
 }

信号量集结构
struct semid_ds
{ struct ipc_perm sem_perm; /* Ownership and permissions */
time_t sem_otime; /* Last semop time */
time_t sem_ctime; /* Last change time */
unsigned short sem_nsems; /* No. of semaphores in set */
};
信号量集函数
semget()函数:用来创建和访问一个信号量集。
int semget(key_t key, int nsems, int semflg);
key:信号集的名字,可以由ftok函数生成。
nsems:信号集中信号量的个数。
semflg: 由九个权限标志构成,它们的用法和创建文件时使用的mode模式标志是⼀样的 。
成功返回信号集的标识码,失败返回-1
semop()函数::用来创建和访问一个信号量集 。
int semop(int semid, struct sembuf *sops, unsigned nsops);
semid:是该信号量的标识码,也就是semget函数的返回值
sops::是个指向一个结构数值的指针
sembuf结构体:
struct sembuf {
short sem_num;
short sem_op;
short sem_flg;
};
sem_num是信号量的编号。
sem_op是信号量一次PV操作时加减的数值,一般只会用到两个值:
一个是“-1”,也就是P操作,等待信号量变得可用;
另⼀个是“+1”,也就是我们的V操作,发出信号量已经变得可用;
sem_flag的两个取值是IPC_NOWAIT或SEM_UNDO
nsops:信号量的个数
返回值:成功返回0,失败返回-1。
semctl()函数:用于控制信号量集。
int semctl(int semid, int semnum, int cmd, …);//可变参数列表
semid::由semget返回的信号集标识码
semnum:信号集中信号量的序号
cmd:将要采取的动作,有三个可取值。
最后一个参数根据命令不同而不同
这里写图片描述
返回值:成功返回0,失败返回-1 。
进程间通信总结
接口方面
创建IPC(msgqueue, shm, sem), ipcget
删除IPC(msgqueue, shm, sem), ipcctl + IPC_RMID
每种IPC都有自己个性化的操作接口
特性方面:
IPC资源必须删除,否则不会自动清除,除非重启,所以system V IPC资源的生命周期随内核
有关于消息队列和共享内存,请移步这两篇博客进程间通信之消息队列篇进程间通信之共享内存篇











    

猜你喜欢

转载自blog.csdn.net/jennifer1_/article/details/81416417