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

来源:互联网 发布:郑州网络销售诈骗 编辑:程序博客网 时间:2024/06/04 00:23

一、共享内存

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

 

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

               相关函数可以参考:Linux 共享内存

#include<stdio.h>#include<stdlib.h>#include<sys/types.h>#include<sys/ipc.h>#include<sys/sem.h>#include"semcom.c"#define SIZE 100int 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 100struct 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 100struct 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;}

 

 

 

 

原创粉丝点击