[linux] linux c实现共享内存读写操作

IPC_PRIVATE

IPC_PRIVATE 是用于创建新的 System V IPC(Inter-Process Communication,进程间通信)对象的特殊键值。在使用 System V 共享内存、消息队列或信号量时,IPC_PRIVATE 可以作为 key 参数传递给 shmgetmsggetsemget 函数,以创建一个新的 IPC 对象, IPC_PRIVATE可以替换为自己的唯一key

特点

  • 唯一性 :使用 IPC_PRIVATE 创建的 IPC 对象是唯一的,只有创建它的进程及其子进程能够访问。这是因为 IPC_PRIVATE 实际上并不是一个真正的键值,而是一个特殊标识符,指示内核为调用进程创建一个新的、唯一的 IPC 对象。
  • 进程间隔离 :由于 IPC_PRIVATE 创建的对象不依赖于一个全局可见的键值,其他进程无法通过键值访问该对象,除非它们是通过继承的方式(如 fork)获得的。

IPC_PRIVATE 例子

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

#define SHM_SIZE 1024  // 共享内存大小

int main() {
    // 创建共享内存段
    int shm_id = shmget(IPC_PRIVATE, SHM_SIZE, IPC_CREAT | 0666);
    if (shm_id == -1) {
        perror("shmget");
        exit(EXIT_FAILURE);
    }

    // 附加共享内存段
    char *shm_ptr = (char *)shmat(shm_id, NULL, 0);
    if (shm_ptr == (char *)-1) {
        perror("shmat");
        exit(EXIT_FAILURE);
    }

    // 写入数据到共享内存
    strncpy(shm_ptr, "Hello, Shared Memory!", SHM_SIZE);

    // 创建子进程
    pid_t pid = fork();
    if (pid == 0) {
        // 子进程读取共享内存
        printf("Child process reads: %s\n", shm_ptr);

        // 分离共享内存段
        if (shmdt(shm_ptr) == -1) {
            perror("shmdt");
            exit(EXIT_FAILURE);
        }
        exit(0);
    } else if (pid > 0) {
        // 父进程等待子进程结束
        wait(NULL);

        // 分离共享内存段
        if (shmdt(shm_ptr) == -1) {
            perror("shmdt");
            exit(EXIT_FAILURE);
        }

        // 删除共享内存段
        if (shmctl(shm_id, IPC_RMID, NULL) == -1) {
            perror("shmctl");
            exit(EXIT_FAILURE);
        }
    } else {
        perror("fork");
        exit(EXIT_FAILURE);
    }

    return 0;
}

自定义Key举例

#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include <sys/shm.h>
#include <errno.h>
#include <stdio.h>
#include <sys/sem.h>

#define DENY_MAC_SHM_SIZE 18  // MAC地址长度为17个字符,加上一个终止符
#define SHM_MAC_INFO_KEY    (0x00260000)
char *g_deny_mac = NULL;
int shm_init(unsigned int key,int shm_id)
{
    //int shm_id = -1;
    void *shm = NULL;
    if(NULL != g_deny_mac) 
    {
        printf("share memory had already init\r\n");
        return 0;
    }
    else
    {
        shm_id = shmget((key_t)SHM_MAC_INFO_KEY,DENY_MAC_SHM_SIZE,IPC_CREAT|0666);
        if(shm_id == -1)
        {
            printf("shmget failed:%s\n",strerror(errno));
            return -1;
        }
        shm = shmat(shm_id,NULL,0);
        g_deny_mac = (char *)shm;
    }
    return 0;
}
int set_deny_mac(char *mac,int len)
{
    int ret = 0;
    void *deny_mac = NULL;
   
    deny_mac = g_deny_mac;
    
    if(mac != NULL)
    {
        
        memcpy(deny_mac,mac,len);
    }
    else
    {
        ret = -1;
    }

    return ret;
}
int get_deny_mac(char *mac, int len)
{
    int ret = -1;
    void *deny_mac = NULL;
    
    deny_mac = g_deny_mac;

    memcpy(mac,g_deny_mac,len);
    if(strlen(mac) == len)
    {
        ret = 0;
    }
    else
    {
        ret = -1;
    }
    
    return ret;
}
void shm_free(int shm_id)
{
    
    void *shm_ptr = shmat(shm_id, NULL, 0);
    if (shm_ptr == (void *)-1) {
        perror("shmat");
        exit(EXIT_FAILURE);
    }
    // 分离共享内存段
    if (shmdt(shm_ptr) == -1) {
        perror("shmdt");
        exit(EXIT_FAILURE);
    }

    // 删除共享内存段
    if (shmctl(shm_id, IPC_RMID, NULL) == -1) {
        perror("shmctl");
        exit(EXIT_FAILURE);
    }

    return ;
}
int main()
{
    char mac[] = "xx:xx:xx:00:00:01";
    char buf[18] = {0};
    int shm_id;

    shm_init(SHM_MAC_INFO_KEY,shm_id);
    get_deny_mac(buf,sizeof(buf));
    printf("buf=%s mac=%s\n",buf,mac); 
    set_deny_mac(mac,18);
    get_deny_mac(buf,18);
    printf("buf=%s mac=%s\n",buf,mac); 
    shm_free(shm_id);
    
    return 0;
}
相关推荐
学Linux的语莫1 小时前
Ansible使用简介和基础使用
linux·运维·服务器·nginx·云计算·ansible
踏雪Vernon1 小时前
[OpenHarmony5.0][Docker][环境]OpenHarmony5.0 Docker编译环境镜像下载以及使用方式
linux·docker·容器·harmonyos
学Linux的语莫1 小时前
搭建服务器VPN,Linux客户端连接WireGuard,Windows客户端连接WireGuard
linux·运维·服务器
legend_jz1 小时前
【Linux】线程控制
linux·服务器·开发语言·c++·笔记·学习·学习方法
Komorebi.py1 小时前
【Linux】-学习笔记04
linux·笔记·学习
黑牛先生1 小时前
【Linux】进程-PCB
linux·运维·服务器
友友马2 小时前
『 Linux 』网络层 - IP协议(一)
linux·网络·tcp/ip
猿java2 小时前
Linux Shell和Shell脚本详解!
java·linux·shell
茶猫_3 小时前
力扣面试题 - 25 二进制数转字符串
c语言·算法·leetcode·职场和发展
A.A呐3 小时前
【Linux第一章】Linux介绍与指令
linux