现在的位置: 首页 > 综合 > 正文

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

2013年12月09日 ⁄ 综合 ⁄ 共 2687字 ⁄ 字号 评论关闭

一、共享内存

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

 

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

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

 

 

 

 

抱歉!评论已关闭.