一、共享内存
最高效的进程间通信机制。多个进程共享一段内存。需要依靠某种同步机制,如互斥锁或信号量。
通常步骤为:创建 -> 映射 -> 使用 -> 撤销映射 ->删除
相关函数可以参考: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;
}