进程间通信(三)---- 信号量

来源:互联网 发布:中文校对软件 编辑:程序博客网 时间:2024/06/14 03:20
信号量的本质是一种数据操作锁,本身不具有数据交换的功能,而是通过控制其他的共享资源(如共享内存)来实现进程间通信,其本身只是一种外部资源的标识,负责保证进程间通信的同步与互斥机制
生命周期不随进程,随内核(与消息队列类似),也存在两个命令ipcs -s(查看系统中的信号量);ipcrm -s semid(释放指定信号量)

所谓同步与互斥机制,互斥表示对于某一公共资源(也叫临界资源),在某一时刻只允许一个访问者对其进行访问,对于进程而言则是在同一时刻仅允许一个进程对当前临界资源进行访问操作,但是互斥无法限制访问者对临界资源的访问顺序,也就是说至于那个进程会占用资源是看这个进程抢占资源的能力的,访问是随机无序的,这样一来就会有一个问题,当一个进程,它访问资源的优先级非常高,抢占资源能力非常强,但是此时它不断的申请锁,但立马又释放锁,不断的重复这些无用的操作,但由于它的优先级非常高,我们又不得不把资源给它,所以这样一来其他的进程就一直无法得到资源,这也就造成了饥饿问题;所以针对这一点,在互斥的基础上,我们又加上了同步机制,即实现了对资源的有序访问,让每个进程都有机会能够申请到资源

信号量与互斥锁,条件变量的区别在于前者针对于进程间的同步与互斥,而后者则是针对于线程间的同步与互斥

对于信号量操作的接口如下:
int semget(key_t key,int num_sems,int sem_flags);
函数功能:创建一个信号量集或获取一个已存在的信号量集
参数:第一个参数由ftok()获得;第二个参数表示要创建的信号量集中信号量的个数;第三个参数主要有两个宏(IPC_CREAT和IPC_EXCL)
返回值:若成功,则返回对应信号量集的标识符;否则返回-1

int semctl(int sem_id,int sem_num,int cmd,...);
函数功能:用于对指定信号量集中的信号量进行操作
参数:第一个参数表示信号量集的标识符;第二个参数表示要进行操作的信号量集的信号量对应下标;第三个参数表示要采取的操作(SETVAL表示对信号量进行初始化,IPC_RMID表示删除一个信号量);若第三个参数是SETVAL,则存在之后的参数(union semun--需要用户自己设置,用于对信号量的某些内容进行初始化)
返回值:若成功返回0,否则返回-1

int semop(int sem_id,struct sembuf* sem_opa,size_t num_sem_ops);
函数功能:用于改变信号量的值(P操作---占用信号量,V操作---释放信号量)
参数:第一个参数表示信号量集的标识符;第二个参数表示struct sembuf的指针(可以看做是一个对应结构体数组,用于对信号量集进行操作);第三个参数表示前面结构体数组大小即要操作的信号量个数
返回值:若成功返回0,否则返回-1

struct sembuf{
      short sem_num;//该成员是信号编号,除非使用一组信号量,否则它为0
      short sem_op;//该成员的值是信号量在一次操作中需要改变的。 //信号量在一次操作中需要改变的数据,通常是两个数,一个是-1,即P(等待)操作,它等待信号量变为可用;一个是+1,即V(发送信号)操作,它发送信号表示信号量现在已可用。
      short sem_flg;//通常为SEM_UNDO,使操作系统跟踪当前进程对这个信号量的修改情况, //并在进程没有释放该信号量而终止时,操作系统释放信号量,防止因进程异常退出而导致的死锁问题
};
原创粉丝点击