1. 共享内存作为进程间通讯的高效方式,在多进程通讯机制中,有信号量、消息队列、套接字和共享内存等方式,但提倡共享内存。

 

2. 共享内存是一个对内存的读写操作,但其需要增加通讯同步方式,例如通过信号量或者线程锁进行同步,因为读写内存都是两个进程或者一个进程内部的两个线程

进行通讯。谈谈线程锁的目的,它主要是通过上锁进行锁定并让其他未上锁的线程进行等待内存的读写完成,因为在一个时刻进行内存读写是不可靠的,会出现数据的异常。

 

3. 阅读具体的shmt代码,第一份是c,第二份是h:

/*
 * Copyright (C) 29178019@qq.com 2022-2023 
 */
#include "shmt.h"

/*
 * @brief init shem
 * @param shmt, data of shmt_operations
 * @param shmt_size, size of shmt
 * @return failed at -1
 */
int shmt_init_mem(struct shmt_operations *shmt, unsigned long shmt_size)
{
    shmt->shmt_key = ftok(SHMT_PATH, 0x6666);

    shmt->shmt_id = shmget(shmt->shmt_key, shmt_size, IPC_CREAT | 0666);
    if ( shmt->shmt_id < 0 )
    {
        printf("failed to get share memory\n");
        return -1;
    }
    if ( shmt_size )
    {
        shmt->shmt_size = shmt_size;
    }

    return 0;
}

/*
 * @brief get address of shmt
 * @param shmt, data of shmt_operations
 * @return failed at NULL
 */
static void *shmt_get_mem_addr(struct shmt_operations *shmt)
{
    void *addr = NULL;
    addr = shmat(shmt->shmt_id,NULL,0);
    if ( !addr )
    {
        printf("faield to map share memory\n");
        return NULL;
    }
    return addr;
}

/*
 * @brief set data to shmt
 * @param msg, msg of setting
 * @param shmt, data of shmt_operations
 * @return failed at -1
 */
int shmt_set_mem_data(struct shmt_operations *shmt,void *msg)
{
    void *addr = NULL;
    addr = shmt_get_mem_addr(shmt);
    if ( NULL == addr )
    {
        printf("failed to get addr of shmem\n");
        return -1;
    }
    memcpy(addr,msg,shmt->shmt_size);
    return 0;
}
/*
 * @brief get data to shmt
 * @param shm, data of shmt_operations
 * @param rsp, msg of getting
 * @return failed at -1
 */
int shmt_get_mem_data(struct shmt_operations *shmt,void *msg)
{
    void *addr = NULL;
    addr = shmt_get_mem_addr(shmt);
    if ( NULL == addr )
    {
        printf("failed to get addr of shmem\n");
        return -1;
    }
    memcpy(msg,addr,shmt->shmt_size);
    return 0;
}

//sample
int main(void)
{
    struct shmt_operations mem = { 0 };
    int ret = -1;
    char set[128] = "talk is cheap, show me the code";
    char get[128] = "";

    ret = shmt_init_mem(&mem,128);
    if ( -1 == ret )
    {
        printf("CziShm_InitShmem failed\n");
        return -1;
    }

    ret = shmt_set_mem_data(&mem,set);
    if ( -1 == ret )
    {
        printf("CziShm_SetShmemData failed\n");
        return -1;
    }

    ret = shmt_get_mem_data(&mem,get);
    if ( -1 == ret )
    {
        printf("CziShm_GetShmemData failed\n");
        return -1;
    }
    printf("the set is %s\n",set);
    printf("the get is %s\n",get);

    return 0;
}

 

/*
 * Copyright (C) 291178019@qq.com 2022-2023 
 */
#ifndef _SHMT_H_
#define _SHMT_H_

#include <stdio.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/shm.h>
#include <string.h>

#define SHMT_PATH "/home/lzh/test/advanced_shmt/src"
#define SHMT_SIZE 1024 * 1024 * 10

struct shmt_operations
{
    key_t shmt_key;            /* key of mem */
    int shmt_id;               /* id of shmt */
    unsigned long shmt_size;   /* size of shmt */

    /* lock etc.. */
};

/* extern functions */
int shmt_init_mem(struct shmt_operations *so, unsigned long size);
int shmt_set_mem_data(struct shmt_operations *so, void *msg);
int shmt_get_mem_data(struct shmt_operations *so, void *msg);

#endif /* _SHMT_H_ */

 该测试代码提供三个封装的接口,该版本是没有线程锁的处理。

可能此时有一种线程锁不应该是在线程之间才可以利用?

没错,shmt_set_mem_data和shmt_get_mem_data都是要在不一样的线程进行操作,但可以并列。

如同a线程可以set,也可以get,但是a线程set,b线程不可以set。

 

4. 加入lock的版本:

 

 可以查看该补丁,即可完成锁版本的共享内存。

 

原文地址:http://www.cnblogs.com/real-watson/p/16815344.html

1. 本站所有资源来源于用户上传和网络,如有侵权请邮件联系站长! 2. 分享目的仅供大家学习和交流,请务用于商业用途! 3. 如果你也有好源码或者教程,可以到用户中心发布,分享有积分奖励和额外收入! 4. 本站提供的源码、模板、插件等等其他资源,都不包含技术服务请大家谅解! 5. 如有链接无法下载、失效或广告,请联系管理员处理! 6. 本站资源售价只是赞助,收取费用仅维持本站的日常运营所需! 7. 如遇到加密压缩包,默认解压密码为"gltf",如遇到无法解压的请联系管理员! 8. 因为资源和程序源码均为可复制品,所以不支持任何理由的退款兑现,请斟酌后支付下载 声明:如果标题没有注明"已测试"或者"测试可用"等字样的资源源码均未经过站长测试.特别注意没有标注的源码不保证任何可用性