linux进程通信--信号量
2016-05-31 20:33
405 查看
信号量的功能
信号量自身并不具有通信功能,而是在当多个进程访问同一资源时,使用信号量实现多个进程之间的互斥与同步,因此信号量相当于数据锁功能。简单的说信号量就是解决不同进程访问共享资源时,避免出现问题而产生的一种机制。
信号量是一个特殊的变量,程序对其访问都是原子操作,且只允许对它进行等待P(-1)操作和发送V(+1)操作。最简单的信号量是只能取0和1的变量,这也是信号量最常见的一种形式,叫做二进制信号量,而可以取多个正整数的信号量被称为通用信号量。
信号量的实现过程
信号量的实现过程:当进程获得信号量时,执行P(-1)操作,进入临界区,此时阻止其它进程对资源的访问,当该进程执行完毕,实行V(+1)操作,离开临界区。其他进程此时可以访问资源。
信号量操作函数
4.应用实例
使用两个进程实现对终端进行输出,使用信号量实现两个进程之间的协调操作。
5.总结
信号量是一种特殊变量,目的就是为了实现多个进程访问同一资源时出现冲突等现象的协调操作。
信号量自身并不具有通信功能,而是在当多个进程访问同一资源时,使用信号量实现多个进程之间的互斥与同步,因此信号量相当于数据锁功能。简单的说信号量就是解决不同进程访问共享资源时,避免出现问题而产生的一种机制。
信号量是一个特殊的变量,程序对其访问都是原子操作,且只允许对它进行等待P(-1)操作和发送V(+1)操作。最简单的信号量是只能取0和1的变量,这也是信号量最常见的一种形式,叫做二进制信号量,而可以取多个正整数的信号量被称为通用信号量。
信号量的实现过程
信号量的实现过程:当进程获得信号量时,执行P(-1)操作,进入临界区,此时阻止其它进程对资源的访问,当该进程执行完毕,实行V(+1)操作,离开临界区。其他进程此时可以访问资源。
信号量操作函数
int semop(int semid, struct sembuf *sops, unsigned nsops); //操作一组信号,实现PV操作 int semget(key_t key, int nsems, int semflg); //nsems表示信号量的数量,通常设为1 //该函数实现当存在信号量时获取信号量,若不存在则创建信号量 //semflag表示创建信号量的标志位,设置为IPC_CREAT与权限标志位或,该方式可以实现不存在时,创建新的信号量,已存在时也不会报错 int semctl(int semid, int semnum, int cmd, ...); 对信号量进行初始化和删除信号量, union semun { int val; /* Value for SETVAL struct semid_ds *buf; /* Buffer for IPC_STAT, IPC_SET unsigned short *array; /* Array for GETALL, SETALL struct seminfo *__buf; /* Buffer for IPC_INFO (Linux-specific) }; unsigned short sem_num; /* semaphore number short sem_op; /* semaphore operation short sem_flg; /* operation flags
4.应用实例
使用两个进程实现对终端进行输出,使用信号量实现两个进程之间的协调操作。
#include <stdio.h> #include <sys/types.h> #include <sys/ipc.h> #include <sys/sem.h> #include <stdlib.h> #include <unistd.h> int sem_id; //定义共用体 union semun { int val; // SETVAL使用的值 struct semid_ds *buf; // IPC_STAT、IPC_SET 使用缓存区 unsigned short *array; // GETALL,、SETALL 使用的数组 struct seminfo *__buf; // IPC_INFO(Linux特有) 使用缓存区 }; //声明函数 int sem_init(); int sem_del(); int semop_p(); int semop_v(); int main(int argc,char *argv[]) { char message='W'; // 初始化输入参数 int sed_num; sem_id=semget((key_t)1234, 1, 0666|IPC_CREAT); //如果输入的参数大于1 则输出的参数为输入的值 否则的话 输出为X; //如果输入的参数大于1 需要对信号量进行初始话 否则的话信号量不起作用 if(argc>1) { //程序第一次被调用 if(!sem_init()) { printf("init semaphore failed\n"); } message=argv[1][0];//输出参数 sleep(2); } //做10个循环 看两个程序同时共用 终端输出是否打架/冲突 for(sed_num=0;sed_num<10;sed_num++) { if(!semop_p()) //挂起信号量 exit(EXIT_FAILURE); printf("The %d ,times send %c,current pid is %d\n",sed_num,message,getpid()); fflush(stdout); sleep(rand()%3);//休眠一会 printf("The %d ,times send %c,current pid is %d\n",sed_num,message,getpid()); fflush(stdout); sleep(rand()%3); if(!semop_v()) //打印完毕 exit(EXIT_FAILURE); sleep(1); } printf("The process %d is sucess\n",getpid()); sleep(5); if(argc>1) { if(!sem_del()) { exit(EXIT_FAILURE); } } exit(0); } int sem_init() { union semun sem_num; sem_num.val=1; if(semctl(sem_id,0,SETVAL,sem_num)==-1) { //exit(EXIT_FAILURE); return 0; } return 1; } int sem_del() { if(semctl(sem_id,0,IPC_RMID)==-1) return 0; else return 1; } int semop_p() { struct sembuf semopler_p; semopler_p.sem_num=0; //对第sem_num 信号量进行操作 这里只有一个信号量所以只用0 semopler_p.sem_op=-1; semopler_p.sem_flg=SEM_UNDO; if(semop(sem_id,&semopler_p,1)==-1) //第三个参数指的是信号量的个数 { return 0; } else return 1; } int semop_v() { struct sembuf semopler_v; semopler_v.sem_num=0; //对第sem_num 信号量进行操作 这里只有一个信号量所以只用0 semopler_v.sem_op=1; semopler_v.sem_flg=SEM_UNDO; if(semop(sem_id,&semopler_v,1)==-1) //第三个参数指的是信号量的个数 { return 0; } else return 1; }
5.总结
信号量是一种特殊变量,目的就是为了实现多个进程访问同一资源时出现冲突等现象的协调操作。
相关文章推荐
- linux搭建zookeeper集群
- #码神学习#第三天
- Linux 进程描述符 task struct
- Linux下的进度条小程序
- linux环境搭建dubbo+zookeeper
- 【linux】find命令详解
- ubuntu永久修改主机名
- Linux下实现一个进度条
- Linux命令之chmod(修改文件权限)
- VMware克隆linux虚拟机后,克隆后的虚拟机如何把网卡eth1修改为eth0 ?
- linux文件权限和访问模式
- CentOS 在线安装mysql5.7
- Linux下的C++程序崩溃时打印崩溃信息
- Linux编程学习环境搭建
- Linux 命令笔记
- linux常用的配置文件, 通过软链接建立与系统配置文件的联系(vim等)
- CentOS7 开源跳板机(堡垒机) Jumpserver
- CentOS 7 安装配置 NFS
- CentOS 7 x64 安装 Ceph
- CentOS 7.0 安装配置 kafka 消息队列