进程间通信之信号量semaphore--linux内核剖析( 六 )
其中ipc_perm 结构是内核给每个进程间通信对象维护的一个信息结构 , 其成员包含所有者用户id , 所有者组id、创建者及其组id , 以及访问模式等;semid_ds结构体中的sem结构是内核用于维护某个给定信号量的一组值的内部结构 , 其结构定义:
struct sem {ushort semval; /* 信号量的当前值 */short sempid; /* 最后一次返回该信号量的进程ID 号 */ushort semncnt; /* 等待semval大于当前值的进程个数 */ushort semzcnt; /* 等待semval变成0的进程个数 */};
常见的SYSTEM V信号量函数关键字和描述符SYSTEM V信号量是SYSTEM V IPC(即SYSTEM V进程间通信)的组成部分 , 其他的有SYSTEM V消息队列 , SYSTEM V共享内存 。 而关键字和IPC描述符无疑是它们的共同点 , 也使用它们 , 就不得不先对它们进行熟悉 。 这里只对SYSTEM V信号量进行讨论 。
IPC描述符相当于引用ID号 , 要想使用SYSTEM V信号量(或MSG、SHM) , 就必须用IPC描述符来调用信号量 。 而IPC描述符是内核动态提供的(通过semget来获取) , 用户无法让服务器和客户事先认可共同使用哪个描述符 , 所以有时候就需要到关键字KEY来定位描述符 。
某个KEY只会固定对应一个描述符(这项转换工作由内核完成) , 这样假如服务器和
客户事先认可共同使用某个KEY , 那么大家就都能定位到同一个描述符 , 也就能定位到同一个信号量 , 这样就达到了SYSTEM V信号量在进程间共享的目的 。
创建和打开信号量创建一个信号量或访问一个已经存在的信号量集 。
int semget(key_t key, int nsems, int oflag)
该函数执行成功返回信号量标示符 , 失败返回-1
参数描述key通过调用ftok函数得到的键值nsems代表创建信号量的个数 , 如果只是访问而不创建则可以指定该参数为0 , 我们一旦创建了该信号量 , 就不能更改其信号量个数 , 只要你不删除该信号量 , 你就是重新调用该函数创建该键值的信号量 , 该函数只是返回以前创建的值 , 不会重新创建;semflg指定该信号量的读写权限 , 当创建信号量时不许加IPC_CREAT, 若指定IPC_CREAT
semget函数执行成功后 , 就产生了一个由内核维持的类型为semid_ds结构体的信号量集 , 返回semid就是指向该信号量集的引索 。
- nsems>0 : 创建一个信的信号量集 , 指定集合中信号量的数量 , 一旦创建就不能更改 。
- nsems==0 : 访问一个已存在的集合
- 返回的是一个称为信号量标识符的整数 , semop和semctl函数将使用它 。
- 创建成功后信号量结构被设置:
.sem_perm 的uid和gid成员被设置成的调用进程的有效用户ID和有效组ID.oflag 参数中的读写权限位存入sem_perm.mode.sem_otime 被置为0,sem_ctime被设置为当前时间.sem_nsems 被置为nsems参数的值1234
该集合中的每个信号量不初始化 , 这些结构是在semctl , 用参数SET_VAL , SETALL初始化的 。#include #include #include #include #include #define SEM_R0400//用户(属主)读#define SEM_A0200//用户(属主)写#define SVSEM_MODE (SEM_R | SEM_A | SEM_R>>3 | SEM_R>>6)int main(int argc,char *argv[]){intc, oflag, semid, nsems;oflag = SVSEM_MODE | IPC_CREAT;//设置创建模式//根据命令行参数e判断是否制定了IPC_EXCL模式while((c = getopt(argc,argv,"e")) != -1){switch(c){case 'e':oflag |= IPC_EXCL;break;}}//判断命令行参数是否合法if (optind != argc -2){printf("usage: semcreate [-e]");exit(-1);}//获取信号量集合中的信号量个数nsems = atoi(argv[optind+1]);//创建信号量 , 通过ftok函数创建一个key , 返回信号量 标识符semid = semget(ftok(argv[optind],0),nsems,oflag);return EXIT_SUCCESS;}
关键字的获取有多种方法使客户机和服务器在同一IPC结构上会合: * 服务器可以指定关键字IPC_PRIVATE创建一个新IPC结构 , 将返回的标识符存放在某处(例如一个文件)以便客户机取用 。 关键字 IPC_PRIVATE保证服务器创建一个新IPC结构 。 这种技术的缺点是:服务器要将整型标识符写到文件中 , 然后客户机在此后又要读文件取得此标识符 。IPC_PRIVATE关键字也可用于父、子关系进程 。 父进程指定 IPC_PRIVATE创建一个新IPC结构 , 所返回的标识符在fork后可由子进程使用 。 子进程可将此标识符作为exec函数的一个参数传给一个新程序 。
- 在一个公用头文件中定义一个客户机和服务器都认可的关键字 。 然后服务器指定此关键字创建一个新的IPC结构 。 这种方法的问题是该关键字可能已与一个 IPC结构相结合 , 在此情况下 , get函数(msgget、semget或shmget)出错返回 。 服务器必须处理这一错误 , 删除已存在的IPC结构 , 然后试着再创建它 。 当然 , 这个关键字不能被别的程序所占用 。
- 通气会|12月4~6日,2020中国信息通信大会将在成都举行
- 中国|浅谈5G移动通信技术的前世和今生
- 星期一|亚马逊:黑五与网络星期一期间 第三方卖家销售额达到48亿美元
- 建设|龙元建设中标中国移动宁波信息通信产业园二期施工项目
- IPO|三旺通信IPO:产品结构相对单一业务规模较小 研发人员占员工总数33%
- 空间|垃圾文件正在吞噬你的C盘空间用这四种方法,还你一个干净的C盘
- 广告点击|广告效果评估:30天的广告时间评估最全面
- 要来|折叠屏iPhone终于要来了!可惜发布的时间有点晚,你愿意等吗?
- 智能手机品|越南手机悄然崛起!创立短短2年时间,在当地接连击退苹果、小米
- 科技|短视频行业领先 云想科技成长空间广阔