IPC:Intern Process Communication
内核进程通信
(1)共享内存:内核会维护主机上的一块内存段 多个进程可以访问内存段。
(2)消息队列:在主机上 指定一个或多个队列,多个进程可以访问。
(3) 旗语(信号量):希望多个进程 错开时间访问同一块区域。
这3个都需要key 通过fd来创建key 文件具备唯一性 ftok
一 共享内存:shm share memory
1.创建key
2.创建共享内存 shmget
3.挂载共享内存 shmat
4.御卸共享内存 shmdt
5.删除共享内存 shmctl
#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
#include <signal.h>
#include <sys/ipc.h>
#include <sys/shm.h>
#include <sys/types.h>
int* p = NULL;
void hand(int n)
{
if(2==n)
{
//卸载
shmdt(p);
exit(0);
}
}
int main()
{
signal(2,hand);
//1创建key
key_t key = ftok(".",'m');
if(-1 == key) printf("ftok error:%m\n"),exit(-1);
printf("ftok %m\n");
//2创建共享内存
int shmid = shmget(key,4096,IPC_CREAT);
if(-1 == shmid) printf("shmid error:%m\n"),exit(-1);
printf("shmid %m\n");
//3挂载共享内存
p = (int*)shmat(shmid,NULL,0);
if(NULL == p) printf("p error:%m\n"),exit(-1);
printf("p %m\n");
//4使用
while(1)
{
printf("%d\n",*p);
sleep(1);
}
return 0;
}
用来查看主机上IPC的命令:ipc
ipcs 查看 -m shm -q msg -s sem
ipcrm 删除 -m shm -q msg -s sem
二 消息队列 smg
1.创建key
2.创建消息队列 msgget
3.收发消息 msgrcv msgsnd
4.删除消息队列 msgctl
函数原型:
#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/msg.h>
int msgget(key_t key, int msgflg);
#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/msg.h>
int msgsnd(int msqid, const void *msgp, size_t msgsz, int msgflg);
ssize_t msgrcv(int msqid, void *msgp, size_t msgsz, long msgtyp,
int msgflg);
#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
#include <signal.h>
#include <sys/msg.h>
#include <sys/ipc.h>
#include <sys/shm.h>
#include <sys/types.h>
#include <string.h>
enum myType{TYPEA,TYPEB,TYPEC};
struct msgbuf
{
long mtype;
char mtext[20];
};
int main()
{
struct msgbuf msg;
msg.mtype = TYPEA;
//1.创建key
key_t key = ftok(".",'q');
if(-1 == key) printf("ftok error:%m\n"),exit(-1);
printf("ftok %m\n");
//2.创建消息队列
int msgid = msgget(key,IPC_CREAT|0666);
//3.接收
int r;
while(1){
memset(msg.mtext,0,20); //清空
r = msgrcv(msgid,&msg,sizeof(msg),TYPEA,IPC_NOWAIT);
printf("r:%d,msg:%s,typs:%d\n",r,msg.mtext,msg.mtype);
sleep(1);
}
return 0;
}
三:信号量 sem
1.创建key
2.创建信号量 semget
3.初始化信号量 semctl
4.使用信号量 semop
5.删除信号量semctl
#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/sem.h>
int semget(key_t key, int nsems, int semflg);
#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
#include <string.h>
#include <sys/sem.h>
#include <signal.h>
#include <sys/types.h>
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) */
};
struct semb{
unsigned short semval; /* semaphore value */
unsigned short semzcnt; /* # waiting for zero */
unsigned short semncnt; /* # waiting for increase */
pid_t sempid; /* ID of process that did last op */
unsigned short sem_num; /* semaphore number */
short sem_op; /* semaphore operation */
short sem_flg; /* operation flags */
};
int main()
{
//1.创建key
key_t key = ftok(".",'s');
if(-1 == key) printf("ftok error:%m\n"),exit(-1);
printf("ftok %m\n");
//2创建信号量
int semid = semget(key,1,IPC_CREAT|0654);
//3初始化
union semun u;
u.val = 5;
semctl(semid,0,IPC_SET,&u);
//使用
struct semb buf;
buf.sem_num = 0; //数组下标
buf.sem_op = -1;
buf.sem_flg = 0;
int n=0;
while(1)
{
printf("吃了%d个月饼!\n",++n);
semop(semid,&buf,1);
}
}