一、信号量的数据结构:
Linux中信号量是通过内核提供的一系列数据结构实现的,这些数据结构存在于内核空间,对它们的分析是充分理解信号量及利用信号量实现进程间通信的基础,下面先给出信号量的数据结构(存在于include/linux/sem.h中),其它一些数据结构将在相关的系统调用中介绍。
struct sem { int semval; /* 信号量的当前值 */ int sempid; /*在信号量上最后一次操作的进程识别号 */ ushort semncnt; /*等待semval大于当前值的进程个数*/ ushort semzcnt; /*等待semval变成0的进程个数*/ };
struct semid_ds { struct ipc_perm sem_perm; /* IPC权限 */ long sem_otime; /* 最后一次对信号量操作(semop)的时间 */ long sem_ctime; /* 对这个结构最后一次修改的时间 */ struct sem *sem_base; /* 在信号量数组中指向第一个信号量的指针 */ struct sem_queue *sem_pending; /* 待处理的挂起操作*/ struct sem_queue **sem_pending_last; /* 最后一个挂起操作 */ struct sem_undo *undo; /* 在这个数组上的undo 请求 */ ushort sem_nsems; /* 在信号量数组上的信号量号 */ };
struct sem_queue { struct sem_queue * next; /* 队列中下一个节点 */ struct sem_queue ** prev; /* 队列中前一个节点, *(q->prev) == q */ struct wait_queue * sleeper; /* 正在睡眠的进程 */ struct sem_undo * undo; /* undo 结构*/ int pid; /* 请求进程的进程识别号 */ int status; /* 操作的完成状态 */ struct semid_ds * sma; /*有操作的信号量集合数组 */ struct sembuf * sops; /* 挂起操作的数组 */ int nsops; /* 操作的个数 */ };
集中数据结构的重要关系见下图
从图中可知,操作这个信号量集合的进程,在系统调用下对信号量集合中的信号值进行操作。此处,注意信号量和信号的区别。
信号量是一个表述进程是否能拥有资源的关键值,信号量集合是一个包括指向要使用信号量的进程等待队列,其他控制信息以及信号量等信息的复杂的结构
二、常见的system V 信号量函数
a)关键字和描述符
system V信号量是system V IPC(即system V进程间通信)的组成部分,其他的有system V消息队列,system V共享内存。
关键字和IPC描述符是它们的共同特点。
IPC描述符相当于引用ID号,要想使用system V信号(或MSG、SHM),就必须用IPC描述符来调用信号量。
而IPC描述符是内核动态提供的(通过semget()来获得),开发者无线让服务器和客户事先认可共同使用哪个
描述符,所以有时候就需要用到关键字KEY来定位描述符。
一个key会关联固定一个对应的描述符(由内核完成),这样服务器和客户事先共享一个共同认可的key,则
就可以同时定位到同一信号的描述符上,这样即可达到system V信号量在进程间的共享
b) 创建和打开信号量
come from /usr/include/sys/sem.h /* Get semaphore. */ extern int semget (key_t __key, int __nsems, int __semflg) __THROW;
2)__nsems值为0,则访问一个已存在的信号量集合
3)__semflg打开方式
返回一个称为信号量标识符的整数,semctl和semop将使用它
创建成功后:
该集合中的信号量不初始化,信号量的初始化是在semctl函数用参数SETVAL和GETVAL实现的
setget()函数执行成功后,就会产生一个内核维持的类型为semid_ds结构体的信号量集,返回semid就是指向该信号量集的索引
c)关键字的获取
有很多方法是客户机和服务器在同一IPC结构上回合:
d)设置信号量的值(PV操作)
c)对信号集实行控制操作(semval的赋值等)
详见:http://blog.csdn.net/hailuoing/article/details/8219461
参考文章:
http://www.360doc.com/content/12/0824/12/8809247_232067949.shtml