一、共享内存
最高效的进程间通信机制。多个进程共享一段内存。需要依靠某种同步机制,如互斥锁或信号量。
通常步骤为:创建 -> 映射 -> 使用 -> 撤销映射 ->删除
相关函数可以参考:Linux 共享内存
#include<stdio.h> #include<stdlib.h> #include<sys/types.h> #include<sys/ipc.h> #include<sys/sem.h> #include"semcom.c" #define SIZE 100 int main(){ pid_t pid; int shmid; char *shm_addr; char buf[SIZE]; if((shmid=shmget(IPC_PRIVATE,SIZE,0666))<0){ //创建一段共享内存 printf("shmget error!\n"); exit(1); }else printf("Create memory: %d\n",shmid); system("ipcs -m"); //显示共享内存情况 if((pid = fork())<0){ printf("fork error!\n"); exit(1); }else if(pid == 0){ //写入内存 sleep(1); //映射内存,第二个参数为0表示自动分配内存,第三个变量为0,设为可读写 if((shm_addr=shmat(shmid,0,0)) == NULL){ printf("shmat error!\n"); exit(1); }else printf("Child attach memory:%p\n",shm_addr); system("ipcs -m"); fgets(buf,SIZE,stdin); strcpy(shm_addr,buf); //撤销映射 if(shmdt(shm_addr)<0){ printf("shmat error!\n"); exit(1); }else printf("child de-attach memory\n"); system("ipcs -m"); exit(0); }else{ //读取内存 if((shm_addr=shmat(shmid,0,0)) == NULL){ printf("shmat error!\n"); exit(1); }else printf("Parent attach memory:%p\n",shm_addr); system("ipcs -m"); waitpid(pid,NULL,0); strcpy(buf,shm_addr); printf("Parent say:%s\n",shm_addr); system("ipcs -m"); if(shmdt(shm_addr)<0){ printf("shmat error!\n"); exit(1); }else{ printf("parent de-attach memory\n"); } system("ipcs -m"); //删除共享内存 if(shmctl(shmid,IPC_RMID,NULL)<0){ printf("shmat delete error!\n"); exit(1); }else{ printf("parent delete memory\n"); } system("ipcs -m"); } return 0; }
二、消息队列
通常的步骤:创建或打开消息队列 -> 添加消息 -> 读取消息 ->控制消息队列。
相关细节之处可以参考:
Linux消息队列
发送消息:
#include<stdio.h> #include<stdlib.h> #include<sys/types.h> #include<sys/ipc.h> #include<sys/sem.h> #include"semcom.c" #define SIZE 100 struct message{ long msg_type; char msg_text[SIZE]; }; int main(){ pid_t pid; int qid; struct message msg; //定义一个消息结构体成员 if((qid=msgget(ftok(".",'a'),0666|IPC_CREAT))<0){ //创建一个消息队列 printf("msgget error!\n"); exit(1); } while(1){ printf("please input msg: "); if(fgets(msg.msg_text,SIZE,stdin)<0){ printf("read error!\n"); exit(1); } msg.msg_type=getpid(); //最后一个参数表示阻塞进程直到发送成功为止 if(msgsnd(qid,&msg,strlen(msg.msg_text),0)<0){ printf("msgsend error!\n"); exit(1); } if(strncmp(msg.msg_text,"quit",4) == 0){ exit(0); } } return 0; }
接收消息:
#include<stdio.h> #include<stdlib.h> #include<sys/types.h> #include<sys/ipc.h> #include<sys/sem.h> #include"semcom.c" #define SIZE 100 struct message{ long msg_type; char msg_text[SIZE]; }; int main(){ pid_t pid; int qid; struct message msg; if((qid=msgget(ftok(".",'a'),0666|IPC_CREAT))<0){ printf("msgget error!\n"); exit(1); } do{ memset(msg.msg_text,0,SIZE); //第三个参数为接收消息在消息队列中的位置,通常为0;第四个量0为阻塞进程 if(msgrcv(qid,&msg,SIZE,0,0)<0){ printf("msgrcv error!\n"); exit(1); } printf("Msg from queue %s\n",msg.msg_text); }while(strncmp(msg.msg_text,"quit",4)); if((msgctl(qid,IPC_RMID,NULL))<0){ printf("msgdel error!\n"); exit(1); } return 0; }