信号量的概述:信号量是用来解决进程之间的同步与互斥问题的一种进程之间通信机制,包括一个称为信号量的变量和在该信号量下等待资源的进程等待队列,以及对信号量进程的两个原子操作(PV操作)。其中信号量对应于某一个资源,取一个非负的整形值。信号量值指的是当前可用的该资源的数量,若它等于0则意味着目前没有可用资源。
PV原子操作的具体定义为:
P操作:如果有可用的资源(信号量值>0),则占用一个资源(给信号量值减一,进入临界区代码),如果没有可用的资源(信号量值等于0),则被阻塞到,知道系统将资源分配给该进程(进入等待队列,一直等到资源轮到该进程)。
V操作:如果在该信号量的等待队列中有进程在等待资源,则唤醒一个阻塞进程。如果没有进程等待它,则释放一个资源(则信号量值加一)。
semget()函数
、
semctl()函数
semop函数
代码分析:
/* sem_com.c */#include "sem_com.h"/* 信号量初始化(赋值)函数*/int init_sem(int sem_id, int init_value) { union semun sem_union; sem_union.val = init_value; /* init_value为初始值 */ if (semctl(sem_id, 0, SETVAL, sem_union) == -1) { perror("Initialize semaphore"); return -1; } return 0;}/* 从系统中删除信号量的函数 */int del_sem(int sem_id) { union semun sem_union; if (semctl(sem_id, 0, IPC_RMID, sem_union) == -1) { perror("Delete semaphore"); return -1; }}/* P操作函数 */int sem_p(int sem_id){ struct sembuf sem_b; sem_b.sem_num = 0; /* 单个信号量的编号应该为0 */ sem_b.sem_op = -1; /* 表示P操作 */ sem_b.sem_flg = SEM_UNDO; /* 系统自动释放将会在系统中残留的信号量*/ if (semop(sem_id, &sem_b, 1) == -1) { perror("P operation"); return -1; } return 0;}/* V操作函数*/int sem_v(int sem_id){ struct sembuf sem_b; sem_b.sem_num = 0; /* 单个信号量的编号应该为0 */ sem_b.sem_op = 1; /* 表示V操作 */ sem_b.sem_flg = SEM_UNDO; /* 系统自动释放将会在系统中残留的信号量*/ if (semop(sem_id, &sem_b, 1) == -1) { perror("V operation"); return -1; } return 0;}