IPC 基本结构 简述 
IPC通信包括:共享内存,消息队列,信号灯
 
共享内存 打开或创建一个共享内存对象,共享内核在内核是什么样子的?  一块缓存,变类似于用户空间的数组或malloc函数分配的空间一样。
查看IPC对象:ipcs -m【查看共享内存】| -q【队列】| -s【信号灯】 删除IPC对象:ipcrm -m | -q | -s id【IPC的ID】
 
共享内存可以通过memcpy写入,也可以通过键盘输入stdin
 
利用键盘输入读取共享内存 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 #include <stdio.h>  #include <sys/types.h>  #include <sys/shm.h>  #include <signal.h>  #include <sys/ipc.h>  #include <unistd.h>  #include <stdlib.h>  int  main ()  {	int  shmid; 	int  key; 	char  *p; 	key = ftok("./myfifo" ,'b' ); 	if (key < 0 ) 	{ 		printf ("create key failure\n" ); 		return  -1 ; 	} 	printf ("create key sucess key = %X\n" ,key); 	shmid = shmget(key,128 ,IPC_CREAT | 0777 ); 	if (shmid<0 ) 	{ 		printf ("create share memory failure\n" ); 		return  -2 ; 	} 	printf ("create share memory sucess shmid = %X\n" ,shmid); 	system("ipcs -m" ); 	p = (char  *)shmat(shmid,NULL ,0 ); 	if (p==NULL ) 	{ 		printf ("shmat func failure\n" ); 		return  -3 ; 	} 	 	fgets(p,128 ,stdin ); 	 	 	printf ("share memory data: %s\n" ,p); 	return  0 ; } 
 
**共享内存特点 **:
共享内存创建之后,一直存在于内核中,直到被删除或系统关闭: 
共享内存和管道不一样,读取后,内容仍在其共享内存中。 
 
1 2 3 4 5 6 7 8 9 10 	 	printf ("share memory data: %s\n" ,p); 	 	printf ("second read :%s\n" ,p); 	shmdt(p); 	system("ipcs -m" ); 	memcpy (p,"abcd" ,4 ); 	return  0 ; 
 
1 2 3 4 5 6 7 8 9 	shmdt(p); 	 	shmctl(shmid,IPC_RMID,NULL ); 	printf ("have delete share memory\n" ); 	system("ipcs -m" ); 	return  0 ; 
 
不同进程之间的通信 
宏IPC_PRIVATE:只可以打开亲属之间的共享内存,不同进程之间的需要ftok来获取shmid。
 
服务端代码,进程通过kill发送SIGUSR1给客户端进程告知已写入share memory。同时接收SIGUSR2信号。 
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 #include <stdio.h>  #include <sys/types.h>  #include <string.h>  #include <sys/shm.h>  #include <signal.h>  #include <sys/ipc.h>  #include <unistd.h>  #include <stdlib.h>  struct  mybuf { 	int  pid; 	char  buf[124 ]; }; void  myfun ()  {	printf ("myfun\n" ); } int  main ()  {	int  shmid; 	int  key; 	struct  mybuf  *p ; 	int  pid; 	key = ftok("./myfifo" ,'b' ); 	if (key < 0 ) 	{ 		printf ("create key failure\n" ); 		return  -1 ; 	} 	printf ("create key sucess key = %X\n" ,key); 	shmid = shmget(key,128 ,IPC_CREAT | 0777 ); 	if (shmid<0 ) 	{ 		printf ("create share memory failure\n" ); 		return  -2 ; 	} 	printf ("create share memory sucess shmid = %X\n" ,shmid); 	signal(SIGUSR2,myfun); 	 	p = (struct mybuf *)shmat(shmid,NULL ,0 ); 	if (p==NULL ) 	{ 		printf ("shmat func failure\n" ); 		return  -3 ; 	} 	 	p->pid = getpid(); 	pause();  	pid = p->pid; 	while (1 ) 	{ 		printf ("parent process start write share memory!\n" ); 		fgets(p->buf,128 ,stdin ); 		kill(pid,SIGUSR1); 		pause(); 	} 	shmdt(p); 	shmctl(shmid,IPC_RMID,NULL ); 	return  0 ; } 
 
客户端代码,进程通过kill发送SIGUSR2给服务端进程告知已读取share memory。同时接收SIGUSR1信号,进行读取。 
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 #include <stdio.h>  #include <sys/types.h>  #include <string.h>  #include <sys/shm.h>  #include <signal.h>  #include <sys/ipc.h>  #include <unistd.h>  #include <stdlib.h>  struct  mybuf { 	int  pid; 	char  buf[124 ]; }; void  myfun ()  {	printf ("myfun\n" ); } int  main ()  {	int  shmid; 	int  key; 	struct  mybuf  *p ; 	int  pid; 	key = ftok("./myfifo" ,'b' ); 	if (key < 0 ) 	{ 		printf ("create key failure\n" ); 		return  -1 ; 	} 	printf ("create key sucess key = %X\n" ,key); 	shmid = shmget(key,128 ,IPC_CREAT | 0777 ); 	if (shmid<0 ) 	{ 		printf ("create share memory failure\n" ); 		return  -2 ; 	} 	printf ("create share memory sucess shmid = %X\n" ,shmid); 	signal(SIGUSR1,myfun); 	 	p = (struct mybuf *)shmat(shmid,NULL ,0 ); 	if (p==NULL ) 	{ 		printf ("shmat func failure\n" ); 		return  -3 ; 	} 	 	 	 	pid = p->pid; 	 	p->pid = getpid(); 	kill(pid,SIGUSR2); 	while (1 ) 	{ 		pause(); 		printf ("client has read: %s\n" ,p->buf); 		kill(pid,SIGUSR2); 	} 	shmdt(p); 	shmctl(shmid,IPC_RMID,NULL ); 	return  0 ; } 
 
消息队列 概念 
其中消息类型要与队列中消息类型进行匹配 
无亲缘关系的读写 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 #include <stdio.h>  #include <sys/types.h>  #include <sys/msg.h>  #include <unistd.h>  #include <signal.h>  #include <string.h>  #include <stdlib.h>  struct  msgbuf { 	long  type; 	char  msg[124 ]; 	char  next[4 ]; }; int  main ()  {	int  msgid; 	int  readret; 	int  key; 	struct  msgbuf  sendbuf ,readbuf ; 	key = ftok("./myfifo" ,'a' ); 	if (key<0 ) 	{ 		printf ("create key failure!\n" ); 		return  -1 ; 	} 	msgid = msgget(key,IPC_CREAT|0777 ); 	if (msgid<0 ) 	{ 		printf ("create msgid  failure!\n" ); 		return  -1 ; 	} 	system("ipcs -q" ); 	 	sendbuf.type = 100 ; 	 	while (1 ) 	{ 		memset (sendbuf.msg,0 ,124 );  		printf ("PLZ inout msg: " ); 		fgets(sendbuf.msg,124 ,stdin ); 		msgsnd(msgid,(void  *)&sendbuf,strlen (sendbuf.msg),0 ); 		 	} 	msgctl(msgid,IPC_RMID,NULL ); 	system("ipcs -q" ); 	return  0 ; } 
 
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 #include <stdio.h>  #include <sys/types.h>  #include <sys/msg.h>  #include <unistd.h>  #include <signal.h>  #include <string.h>  #include <stdlib.h>  struct  msgbuf { 	long  type; 	char  msg[124 ]; 	char  next[4 ]; }; int  main ()  {	int  msgid; 	int  readret; 	int  key; 	struct  msgbuf  sendbuf ,readbuf ; 	key = ftok("./myfifo" ,'a' ); 	if (key<0 ) 	{ 		printf ("create key failure!\n" ); 		return  -1 ; 	} 	msgid = msgget(key,IPC_CREAT|0777 ); 	if (msgid<0 ) 	{ 		printf ("create msgid  failure!\n" ); 		return  -1 ; 	} 	system("ipcs -q" ); 	 	sendbuf.type = 100 ; 	 	while (1 ) 	{ 		memset (readbuf.msg,0 ,124 );  		msgrcv(msgid,(void  *)&readbuf,124 ,100 ,0 ); 		printf ("recv msg : %s\n" ,readbuf.msg);		 	} 	msgctl(msgid,IPC_RMID,NULL ); 	system("ipcs -q" ); 	return  0 ; } 
 
信号灯 概念 信号灯 :信号灯集合(可以包含多个信号灯)PC对象是一个信号灯集(多个信号量)
利用信号灯进行通信 
利用ftok创建key,然后构建信号灯。首先运行客户端,信号量初始化在客户端上,并进行V操作,所以信号量资源被释放,无法利用。下一步执行服务端,服务端先执行任务,然后发送P操作信息,由此分配资源给客户端。
 
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 #include <stdio.h>  #include <unistd.h>  #include <pthread.h>  #include <stdlib.h>  #include <sys/ipc.h>  #include <sys/sem.h>  union  semun { 	int  val; 	struct  semid_ds  *buf ; 	unsigned  short  *array ; 	struct  seminfo  *_buf ; }; int  semid;union  semun  mysemun ;struct  sembuf  mysembuf ;int  main ()  {	int  i; 	int  key; 	key = ftok("./myfifo" ,'a' ); 	if (key<0 ) 	{ 		printf ("create key failure!" ); 		return  -1 ; 	} 	printf ("create key sucess! key=%d\n" ,key); 	semid = semget(key,3 ,IPC_CREAT|0777 ); 	if (semid<0 ) 	{ 		printf ("create semid failure!" ); 		return  -1 ; 	} 	printf ("create semid sucess! semid = %d\n" ,semid); 	system("ipcs -s" ); 	 	mysembuf.sem_num = 0 ; 	mysembuf.sem_flg = 0 ; 	for (i=0 ; i<10 ; i++) 	{ 		usleep(100 ); 		printf ("this is main func i=%d\n" ,i); 	} 	 	 	mysembuf.sem_op =1 ; 	semop(semid,&mysembuf,1 ); 	while (1 ); 	return  0 ; 	 } 
 
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 #include <stdio.h>  #include <unistd.h>  #include <pthread.h>  #include <stdlib.h>  #include <sys/ipc.h>  #include <sys/sem.h>  union  semun { 	int  val; 	struct  semid_ds  *buf ; 	unsigned  short  *array ; 	struct  seminfo  *_buf ; }; int  semid;union  semun  mysemun ;struct  sembuf  mysembuf ;int  main ()  {	int  i; 	int  key; 	key = ftok("./myfifo" ,'a' ); 	if (key<0 ) 	{ 		printf ("create key failure!" ); 		return  -1 ; 	} 	printf ("create key sucess\n" ); 	semid = semget(key,3 ,IPC_CREAT|0777 ); 	if (semid<0 ) 	{ 		printf ("create semid failure!" ); 		return  -1 ; 	} 	printf ("create semid sucess\n" ); 	system("ipcs -s" ); 	 	mysemun.val = 0 ; 	semctl(semid,0 ,SETVAL,mysemun); 	mysembuf.sem_num = 0 ; 	mysembuf.sem_flg = 0 ; 	 	mysembuf.sem_op=-1 ; 	semop(semid,&mysembuf,1 ); 	for (i=0 ; i<10 ; i++) 	{ 		usleep(100 ); 		printf ("this is main func i=%d\n" ,i); 	} 	 	 	 	 	while (1 ); 	return  0 ; 	 }