linux进程通信--共享内存

特点

共享内存是linux进程进行通信的一种高效的传递方式,linux内核在内存中留下一块存储区,进程通过将共享内存的地址映射到进程空间,就可以实现直接对数据进行操作,但是共享内存自身没有同步机制,因此需要适用其他的方式实现对共享内存空间的读写进行同步。通信结构简图如图1所示。

                        图1 多进程共享内存通信原理示意图

实现过程与操作函数

共享内存的操作分为以下几个步骤:

  • 创建共享内存
  • 映射共享内存
  • 删除共享内存
  • 释放共享内存
    /************************************

    int shmget(key_t key, size_t size, int shmflg);
    //创建共享内存
    //size 共享内存的大小,
    shmflag类似于前面的消息队列和信号量的创建,
    采用一般采用0666|IPC_CREAT,实现不存在内存空间的时候实现创建,存
    在的时候实现获取共享内存,返回创建的内存的标志符


----------

    void *shmat(int shmid, const void *shmaddr, int shmflg);
    //映射共享内存
     shmid为创建时的标志符;
    shmaddr:将共享内存映射到指定位置(若为 0 则表示把该段共享内存
            映射到调用进程的地址空间)
    shmflg:
            SHM_RDONLY:共享内存只读
            默认 0:共享内存可读写

----------

    int shmdt(const void *shmaddr);
        //释放共享内存Shmaddr:被映射的共享内存段地址,


----------

    int shmctl(int shmid, int cmd, struct shmid_ds *buf);
        // 删除共享内存   
    shmid
        共享内存标识符
    cmd
        IPC_STAT:得到共享内存的状态,把共享内存的shmid_ds结构复制到buf中
        IPC_SET:改变共享内存的状态,把buf所指的shmid_ds结构中的
                uid、gid、mode复制到共享内存的shmid_ds结构内
        IPC_RMID:删除这片共享内存
    buf 
        共享内存管理结构体。

    /*************************************************/

应用实例

实现两个进程通过共享内存交换数据,发送端接收终端数据,发送至共享内存,读取端从共享内存读取数据,实现数据的交换。由于共享内存自身无法实现进程同步,因此定义了write_flag标志位,作为读写的标志实现

读取端例程

#include
#include 
#include 
#include 
#include 
#include "shmheader.h"
#include `
int main()
{
int shm_id;
int run_flag=1;
void *shm_mem=NULL;
struct shared_mem *shared;//用来存放地址
shm_id=shmget((key_t)1234,sizeof(struct shared_mem),0666|IPC_CREAT);// 创建共享内存
if(shm_id==-1)
{
    printf("Creat shared_mem failed\n");
    exit(EXIT_FAILURE);
}
// 将共享内存链接到当前进程
shm_mem=shmat(shm_id,(void *)0,0);
if(shm_mem==(void *)-1)
{
    printf("connect memeory failed\n");
    exit(EXIT_FAILURE);
}
//打印地址
shared=(struct shared_mem *)shm_mem;
shared->write_flag=0;
while(run_flag)
{
    if(shared->write_flag==1)//   等待写结束
    {
        printf("You Write is:%s",shared->text);
        sleep(1);
        shared->write_flag=0;
        if(strncmp(shared->text,"end",3)==0)
        {
            run_flag=0;
        }
    }
}
if(shmdt(shm_mem)==-1)
{
    printf("disconnect memeory failed!\n");
    exit(EXIT_FAILURE);
}
//读取结束要删除共享内存
if(shmctl(shm_id,IPC_RMID,0)==-1)
{
    printf("delete memeory failed!\n");
    exit(EXIT_FAILURE);

}
sleep(2);
return 0;
}`

发送端例程

#include
#include 
#include 
#include 
#include 

#include 

#include "shmheader.h"

#define BUF_SIZE 512

int main()
{
    int shm_id;
    int run_flag=1;
    void *shm_mem=NULL;
    struct shared_mem *shared;//用来存放地址
    char buffer[BUF_SIZE+1];
    shm_id=shmget((key_t)1234,sizeof(struct shared_mem),0666|IPC_CREAT);// 创建共享内存
    if(shm_id==-1)
    {
        printf("Creat shared_mem failed\n");
        exit(EXIT_FAILURE);
    }
    // 将共享内存链接到当前进程
    shm_mem=shmat(shm_id,(void *)0,0);
    if(shm_mem==(void *)-1)
    {
        printf("connect memeory failed\n");
        exit(EXIT_FAILURE);
    }
    //打印地址
//  printf("share mameory adress is %X\n",(int)shm_mem);
    shared=(struct shared_mem*)shm_mem;
    //shared.write_flag=1;  //关闭写
    while(run_flag)
    {
        //一直检测写
        while(shared->write_flag)   //如果 一直不可写再次等待
        {
            sleep(1);
            printf("please waiting ....\n");
        }
        printf("please write :");
        fgets(buffer,BUF_SIZE,stdin);
        strncpy(shared->text,buffer,BUF_SIZE);

        shared->write_flag=1;
        if(strncmp(buffer,"end",3)==0)
        {
            run_flag=0;
        }
    }
    if(shmdt(shm_mem)==-1)
    {
        printf("disconnect memeory failed!\n");
        exit(EXIT_FAILURE);
    }
    sleep(2);

    return 0;
}

头文件

#ifndef _SHMHEADER_H
#define _SHMHEADER_H

#define TEXT_SIZE 2048
struct shared_mem
{

    int write_flag;//定义的读写标志位
    char text[TEXT_SIZE];
};

#endif

总结

使用共享内存实现进程通信,接口简单、通信方便、效率高;但是缺乏同步机制,需要借用其他的方法实现同步。

你可能感兴趣的:(linux,linux系统编程与驱动基础)