[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;
}
相关推荐
南玖yy2 分钟前
C语言:数组的介绍与使用
c语言·开发语言·算法
黑牛先生10 分钟前
【Linux】动静态库
linux·运维·服务器
vortex511 分钟前
Shell基础:中括号的使用
linux·运维·bash·shell
Icomi_2 小时前
【PyTorch】7.自动微分模块:开启神经网络 “进化之门” 的魔法钥匙
c语言·c++·人工智能·pytorch·python·机器学习·计算机视觉
ElvInR3 小时前
【C语言】动态内存管理
c语言·开发语言
-VE-4 小时前
myshell
linux·c++
嘻嘻哈哈的zl5 小时前
初级数据结构:栈和队列
c语言·开发语言·数据结构
weixin_537590456 小时前
《C程序设计》第六章练习答案
c语言·c++·算法
身在江湖的郭大侠6 小时前
Linux内核
linux·服务器
charlie1145141917 小时前
从0开始使用面对对象C语言搭建一个基于OLED的图形显示框架(OLED设备层封装)
c语言·stm32·单片机·教程·oled·嵌入式软件