Linux进程间通信(二)——共享内存、消息队列

一、共享内存

                  最高效的进程间通信机制。多个进程共享一段内存。需要依靠某种同步机制,如互斥锁或信号量。

 

                 通常步骤为:创建 -> 映射 -> 使用 -> 撤销映射 ->删除

               相关函数可以参考: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;  
}  

来源: http://blog.csdn.net/fansongy/article/details/6867475

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值