0
点赞
收藏
分享

微信扫一扫

互斥锁+共享内存封装库,实现进程间通讯(Linux)

数数扁桃 2022-05-04 阅读 109

Linux下提供了多种共享内存的通讯机制,常用的就是socket,但是socket通讯使用简单,但性能不佳,最优的方式还是共享内存方式。本章分享封装库,就是基于共享内存实现的。

封装库连接

(66条消息) 互斥锁+共享内存封装库,实现进程间通讯(Linux)-C文档类资源-CSDN文库

共享内存Linux提供了三种方式:

  1. POSIX共享内存对象
  2. POSIX内存映射文件
  3. SYSTEM V共享内存

这三种方式的区别,就不分析了,大家可以网上检索一下。

本章分享的基于第二种方式“POSIX内存映射文件”实现的。

设计的要求

1:使用进程间的互斥锁,实现了共享内存共享数据的互斥访问问题

2:有效数据部分,通过分配器来管理内存的开辟和释放

3:实现了一对多的订阅/发布模型(一端发送,多端接收的模型)

设计的架构图

 接口定义

#ifndef __DEVIN_SHM_FIFO_H__
#define __DEVIN_SHM_FIFO_H__


void *devin_shm_fifo_init(char *topic);
void devin_shm_fifo_destory(void *handle);

int devin_shm_fifo_read(void *handle, void *buf, int max_buf_len, int *datalen);
// 写入端有一次拷贝 (将数据拷贝到共享内存区域)
int devin_shm_fifo_write(void *handle, const void *data, int datalen);

// 零拷贝的操作 (仅用于发送或写入端)
// 从共享内存中获的可用的空间,返回地址
int devin_shm_fifo_get_addr(void *handle, void **addr, void **addr_param, int datalen);
// 数据写入共享内存后,及时同步到接收端
int devin_shm_fifo_write_sync(void *handle, void *addr, void *addr_param, int datalen);

#endif

接口使用示例

// 订阅方

#include <stdio.h>
#include <unistd.h>
#include <string.h>
#include <sys/time.h>
#include "devin_shm_fifo.h"

int main()
{
    char            *topic = "topic";
    void            *shmfifo = NULL;
    char            buffer[1024*1024*3] = {0};
    int             i = 0;
    int             ret = -1;
	struct timeval 	cur_time;
    int             datalen = 0;

    shmfifo = devin_shm_fifo_init(topic);
    if(!shmfifo)
    {
        printf("devin_shm_fifo_init fail\n");
        return -1;
    }

int mm = 0;
    while (1)
    {
        memset(buffer, 0, sizeof(buffer));
        ret = devin_shm_fifo_read(shmfifo, buffer, sizeof(buffer), &datalen);
        if(ret == 0)
        {
            gettimeofday(&cur_time,NULL);
            printf("%05d, %s, %ld\n", mm++, buffer, cur_time.tv_sec * 1000000 + cur_time.tv_usec);
        }else{
            //printf("xxxxxxx : %d\n", ret);
        }
        usleep(5*1000);
    }

    devin_shm_fifo_destory(shmfifo);


    return 0;
}
// 发布方:

#include <stdio.h>
#include <unistd.h>
#include <string.h>
#include <sys/time.h>
#include "devin_shm_fifo.h"

int main()
{
    char            *topic = "topic";
    void            *shmfifo = NULL;
    char            buffer[1024*1024*3] = {0};
    int             i = 0;
    int             ret = -1;
    void            *addr = NULL;
    void            *addr_param = NULL;
	struct timeval 	cur_time;

    shmfifo = devin_shm_fifo_init(topic);
    if(!shmfifo)
    {
        printf("shmfifo_init fail\n");
        return -1;
    }

    while (1)
    {
        memset(buffer, 0, sizeof(buffer));
		gettimeofday(&cur_time,NULL);
        snprintf(buffer, sizeof(buffer), "aaaaa%05d, time: %ld", i++, cur_time.tv_sec * 1000000 + cur_time.tv_usec);
        
send:
        // 获取指定大小的空间地址
        ret = devin_shm_fifo_get_addr(shmfifo, &addr, &addr_param, sizeof(buffer));
        if(ret < 0)
        {
            printf("devin_shm_fifo_get_addr ret = %d\n", ret);
            goto send;
        }

        // 给空间填充数据
        memcpy(addr, buffer, sizeof(buffer));
        
        // 数据同步到接收端
        ret = devin_shm_fifo_write_sync(shmfifo, addr, addr_param, sizeof(buffer));
        if(ret < 0)
        {
            printf("devin_shm_fifo_write_sync ret = %d\n", ret);
        }else{
            printf("%s\n", buffer);
        }

        usleep(10*1000);
    }

    //void shmfifo_get(shmfifo_t *fifo, void *buf);
    devin_shm_fifo_destory(shmfifo);


    return 0;
}
举报

相关推荐

0 条评论