4. 进程间通信--共享内存、信号灯
2017-08-18 本文已影响0人
石不琢
共享内存
共享内存是一种最为高效的进程间通信方式,进程可以直接读写内存,而不需要任何数据的拷贝.
int shmget(key_t key, size_t size, int shmflg);
功能:创建并打开共享内存
void *shmat(int shmid, const void *shmaddr, int shmflg);
功能:映射:在当前进程获得一个共享内存的访问地址
int shmdt(const void *shmaddr);
功能:解除映射:解除共享内存的访问权
int shmctl(int shmid, int cmd, struct shmid_ds *buf);
功能:删除共享内存
/*共享内存:最高效的通信方式*/
//向共享内存中写数据
#include <stdio.h>
#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/shm.h>
#include <stdlib.h>
struct shmbuf{
int a;
float b;
char c;
};
int main(int argc, const char *argv[])
{
/*创建并打开共享内存*/
key_t key = ftok(".", 1);
int shmid = shmget(key, sizeof(struct shmbuf), IPC_CREAT|0664 );
if(shmid == -1)
{
perror("shmget error");
exit(1);
}
/*映射:在当前进程获得一个共享内存的访问地址*/
struct shmbuf *p;
p = (struct shmbuf *)shmat(shmid, NULL, 0);
/*访问:写*/
p->a = 10;
p->b = 12.34;
p->c = 'G';
/*解除映射:解除共享内存的访问权*/
shmdt(p);
system("ipcs -m");
return 0;
}
/*共享内存:最高效的通信方式*/
//从共享内存中读数据
#include <stdio.h>
#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/shm.h>
#include <stdlib.h>
struct shmbuf{
int a;
float b;
char c;
};
int main(int argc, const char *argv[])
{
/*创建并打开共享内存*/
key_t key = ftok(".", 1);
int shmid = shmget(key, sizeof(struct shmbuf), IPC_CREAT|0664 );
if(shmid == -1)
{
perror("shmget error");
exit(1);
}
/*映射:在当前进程获得一个共享内存的访问地址*/
struct shmbuf *p;
p = (struct shmbuf *)shmat(shmid, NULL, 0);
/*访问:读*/
printf("shm: %d--%f--%c\n",p->a,p->b,p->c);
/*解除映射:解除共享内存的访问权*/
shmdt(p);
system("ipcs -m");
return 0;
}
信号灯
int semget(key_t key, int nsems, int semflg);
功能:创建信号灯
参数:nsems:创建的信号灯中信号量的个数
int semctl(int semid, int semnum, int cmd);
int semctl(int semid, int semnum, int cmd, union semun).
功能:设置信号灯值,删除信号量、获取信号量
参数:semnum:选择操作的信号量编码
cmd:执行的命令 SETVAL GETVAL(需要第四个参数) IPC_RMID
int semop(int semid, struct sembuf * sops, unsigned nsops);
功能 :执行PV操作
参数 :
sops:
unsigned short sem_num; / * semaphore number * /
short sem_op; / * semaphore operation * /
short sem_flg; / * operation flags * /
nsops:同时操作信号量的个数
#include <stdio.h>
#include <sys/ipc.h>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/sem.h>
int main(int argc, const char *argv[])
{
//创建信号灯
key_t key = ftok(".", 1);
int semid = semget(key, 1, IPC_CREAT|0664);
if(semid == -1)
{
perror("semget error");
return -1;
}
//设置信号灯中某一个信号量的初始值
union semun semun;
semun.val = 3;
semctl(semid, 0, SETVAL, semun);
//获取信号灯中某一个信号量的初始值
printf("val = %d\n",semctl(semid, 0, GETVAL));
//P:消耗信号灯中某一个信号量值
struct sembuf sembuf;
sembuf.sem_num = 0; //信号灯中信号量的编码
sembuf.sem_op = -2; //一次性消耗2个信号量值
sembuf.sem_flg = 0; //阻塞模式 ,非阻塞(IPC_NOWAIT)
semop(semid, &sembuf, 1);
printf("val = %d\n",semctl(semid, 0, GETVAL));
//V:增加信号灯中某一个信号量值
sembuf.sem_num = 0; //信号灯中信号量的编码
sembuf.sem_op = 5; //一次性增加5个信号量值
sembuf.sem_flg = 0; //阻塞模式 ,非阻塞(IPC_NOWAIT)
semop(semid, &sembuf, 1);
printf("val = %d\n",semctl(semid, 0, GETVAL));
//销毁
system("ipcs -s");
semctl(semid, 0, IPC_RMID);
system("ipcs -s");
return 0;
}