进程通信之共享内存与信号量
2016-04-30 14:41
405 查看
信号量:通过设置一个值val大于0的整数,表示当前最多允许val个进程进入临界区。同时定义P函数,函数中对val进行减1操作,每当一个进程进入临界区时执行一次P函数,当val为0时当前进程等待。定义V函数,对val进行加1操作,当一个进程离开临界区执行V函数。
结构如下:
linux下封装了对信号量的操作函数semget semop semctl需要引用头文件#include <sys/sem.h>
有些情况下可能会用到头文件sys/types.t和sys/ipc.h
semid = semget((key_t)1234,1,IPC_CREAT|0666);1表示创建信号量集中信号量的个数,常用1。
sem_union.val = 1;//设置信号量的值为1,sem_union位联合体自己定义
semctl(semid,0,SETVAL,sem_union);0为常用,SETVAL表示设置信号量的值。
struct sembuf sem_b;
sem_b.sem_num = 0;//常用
sem_b.sem_op = 1;//1为V操作 -1为P操作
sem_b.sem_flg = SEM_UNDO;//常用
semop(semid,&sem_b,1);//1表示参数2表示的数组元素个数
共享内存用于多个进程之间互相通信。linux封装以下函数进行操作。
shmget shmat shmdt shmctl
其中shmget((key_t)1234,1024,IPC_CREAT|0666),1024表示共享内存空间大小,IPC_CREAT|0666表示访问权限和不存在就创建。
删除共享内存空间:shmctl(shmid,IPC_RMID,NULL);shmid为shmget的返回值。
使用共享内存之前需要将共享内存附加到进程的内存空间:shmat(shmid,NULL,0)表示由系统决定附加到的空间位置,不推荐自己指定。shmat返回一个void指针类型,可以强制转化成其他数据类型,用来进行数据传递。如int *data = shmat();
当不使用该共享内存时,需要将它与进行分离。shmdt(data);将shmat的指针传进来即可。
需要头文件<sys/shm.h>
接下来给出两段代码综合使用了信号量和共享内存。这两段代码大同小异。在semc1.c中将共享内存的值改为1,在semc2.c中输出共享值,并将共享值改为2。分别睡眠不同时间。
运行结果应该是1和2混合出现。
结构如下:
P(); //临界区 V();
linux下封装了对信号量的操作函数semget semop semctl需要引用头文件#include <sys/sem.h>
有些情况下可能会用到头文件sys/types.t和sys/ipc.h
semid = semget((key_t)1234,1,IPC_CREAT|0666);1表示创建信号量集中信号量的个数,常用1。
sem_union.val = 1;//设置信号量的值为1,sem_union位联合体自己定义
semctl(semid,0,SETVAL,sem_union);0为常用,SETVAL表示设置信号量的值。
struct sembuf sem_b;
sem_b.sem_num = 0;//常用
sem_b.sem_op = 1;//1为V操作 -1为P操作
sem_b.sem_flg = SEM_UNDO;//常用
semop(semid,&sem_b,1);//1表示参数2表示的数组元素个数
共享内存用于多个进程之间互相通信。linux封装以下函数进行操作。
shmget shmat shmdt shmctl
其中shmget((key_t)1234,1024,IPC_CREAT|0666),1024表示共享内存空间大小,IPC_CREAT|0666表示访问权限和不存在就创建。
删除共享内存空间:shmctl(shmid,IPC_RMID,NULL);shmid为shmget的返回值。
使用共享内存之前需要将共享内存附加到进程的内存空间:shmat(shmid,NULL,0)表示由系统决定附加到的空间位置,不推荐自己指定。shmat返回一个void指针类型,可以强制转化成其他数据类型,用来进行数据传递。如int *data = shmat();
当不使用该共享内存时,需要将它与进行分离。shmdt(data);将shmat的指针传进来即可。
需要头文件<sys/shm.h>
接下来给出两段代码综合使用了信号量和共享内存。这两段代码大同小异。在semc1.c中将共享内存的值改为1,在semc2.c中输出共享值,并将共享值改为2。分别睡眠不同时间。
//semc1.c #include <stdio.h> #include <unistd.h> #include <sys/sem.h> #include <sys/shm.h> union semun { int val; struct semid_ds *buf; unsigned short *array; }; int sem_p(); int sem_v(); int semid; int main(int argc,char *argv[]) { int flag,i,shmid,*shmdata; key_t key; union semun sem_union; flag = IPC_CREAT|0666; key = ftok(".",'a'); if(key == -1) return -1; semid = semget(key,1,flag);//cluster contain 1 sem if(semid == -1) return -1; shmid = shmget(key,1024,flag); shmdata = (int *)shmat(shmid,NULL,0); sem_union.val = 1; semctl(semid,0,SETVAL,sem_union); for(i=0;i<10;i++) { if(!sem_p()) return -1; *shmdata = 1; if(!sem_v()) return -1; sleep(2); } shmdt(shmdata); shmctl(shmid,IPC_RMID,NULL); semctl(semid,0,IPC_RMID,sem_union); return 0; } int sem_p() { struct sembuf sem_b; sem_b.sem_num = 0; sem_b.sem_op = -1; sem_b.sem_flg = SEM_UNDO; if(semop(semid,&sem_b,1)==-1) return 0; return 1; } int sem_v() { struct sembuf sem_b; sem_b.sem_num = 0; sem_b.sem_op = 1; sem_b.sem_flg = SEM_UNDO; if(semop(semid,&sem_b,1)==-1) return 0; return 1; } //semc2.c #include <stdio.h> #include <unistd.h> #include <sys/sem.h> #include <sys/shm.h> int sem_p(); int sem_v(); int semid; int main(int argc,char *argv[]) { int flag,i,shmid,*shmdata; key_t key; flag = IPC_CREAT|0666; key = ftok(".",'a'); if(key == -1) return -1; semid = semget(key,1,flag);//cluster contain 1 sem if(semid == -1) return -1; shmid = shmget(key,1024,flag); shmdata = (int *)shmat(shmid,NULL,0); for(i=0;i<10;i++) { if(!sem_p()) return -1; printf("%d",*shmdata); *shmdata = 2; if(!sem_v()) return -1; usleep(1500000); } shmdt(shmdata); return 0; } int sem_p() { struct sembuf sem_b; sem_b.sem_num = 0; sem_b.sem_op = -1; sem_b.sem_flg = SEM_UNDO; if(semop(semid,&sem_b,1)==-1) return 0; return 1; } int sem_v() { struct sembuf sem_b; sem_b.sem_num = 0; sem_b.sem_op = 1; sem_b.sem_flg = SEM_UNDO; if(semop(semid,&sem_b,1)==-1) return 0; return 1; }
运行结果应该是1和2混合出现。
相关文章推荐
- win32下进程间通信(共享内存)实例分析
- linux多线程编程详解教程(线程通过信号量实现通信代码)
- 单台服务器的PHP进程之间实现共享内存的方法
- PHP信号量基本用法实例详解
- PHP共享内存用法实例分析
- Linux进程通信(IPC)方式简介
- Web跨浏览器进程通信(Web跨域)
- JAVA 多线程之信号量(Semaphore)实例详解
- Linux设备驱动并发控制详解(自旋锁,信号量)
- 共享内存实现进程间大数据的交换
- php-共享内存以及利用共享内存实现消息队列
- 信号量
- 共享内存
- 信号量、互斥锁,读写锁和条件变量的区别
- Linux 进程间通信 - 共享内存(转)
- linux 共享内存(转)
- 共享内存
- KSM(Kernel Samepage Merging) 剖析:Linux 内核中的内存去耦合[转]
- 互斥锁与条件变量的配合!
- 信号量 互斥锁 条件变量的区别