SystemV Posix 共享内存

本文详细介绍了SystemV和Posix两种共享内存机制。在SystemV中,使用ftok生成key,通过shmget创建或获取共享内存,接着用shmat映射到进程空间,shmdt进行断开,shmctl用于管理和删除。Posix方式基于文件,通过shm_open创建或打开共享内存,使用shm_unlink删除,mmap进行映射,ftruncate调整大小。提供了相关的示例代码,包括shmget.c、shmrmid.c、shmwrite.c、shmread.c等。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

 

SystemV:

用到的函数:

ftok : 生成一个32位整数, shmget第一个参数需要用到. 相同的key,返回相同的shmid

shmget : 用于创建或获取一个共享内存。返回一个id用于标识这块IPC对象;

shmat: 把共享内存映射到进程地址空间.

shmdt : 断开映射.与shmat,作用相反;

shmctl : 获取共享内存属性(大小,权限,创建时间,pid....). 删除共享内存

 

Posix: 基于文件

共享内存信号量结合使用 mmap : 共享内存信号量

shm_open:  创建或打开一个 /dev/shm 的共享内存 

shm_unlink : 删除 /dev/shm 共享内存

mmap : 把共享内存(文件) 映射到进程内 . 用于读写, 相对于 shmat 的用作

ftruncate : 更改内存大小

 

例子:

System V:

shmget.c :

创建一个共享内存

#include <stdio.h>
#include <unistd.h>
#include <sys/shm.h>
#include <sys/ipc.h>
#include <stdlib.h>
#include <string.h>
int main(int argc, char ** argv)
{
    if(argc != 3){
        printf("pathname , size\n");
        return 0;
    }

    char *pathname = argv[1];
    int len = atoi(argv[2]);
    printf("pathname:%s, len:%d\n",pathname,len);

    //ftok -> 生成一个key , 用于标示一个ipc对象.
    int key = ftok(pathname , 0);
    printf("key : %d\n" , key);

    //创建或者获取一个共享内存. 返回一个共享内存的标示.
    //相同的key , 返回相同的shmid
    int shmid = shmget(key,len,IPC_CREAT|0644);
    printf("shmid:%d\n",shmid);

    //映射到当前的进程地址空间中.之后进行读写
    char*p = (char*)shmat(shmid,NULL,0);

    printf("p:%p\n",p);
    struct shmid_ds shmbuf;

    //shmctl 可获取shm的状态,也可以删除共享内存
    shmctl(shmid,IPC_STAT,&shmbuf);
    printf("size:%ld,creator pid:%d,links:%ld\n",
    shmbuf.shm_segsz,shmbuf.shm_cpid,shmbuf.shm_nattch);

    //取消映射,相当于断开链接.注意,删除需要用shmctl
    shmdt(p);

    return 0;
}

 

 

shmrmid.c :

用于删除一个共享内存

#include <stdio.h>
#include <unistd.h>
#include <sys/shm.h>
#include <sys/ipc.h>
#include <stdlib.h>
#include <string.h>
int main(int argc, char ** argv)
{

    if(argc != 2){
        printf("pathname \n");
        return 0;
    }
    int key = ftok(argv[1],0);
    printf("key:%d\n" , key);
    int shmid = shmget(key,0,0644);
    printf("shmid:%d\n" , shmid);
    shmctl(shmid,IPC_RMID,NULL);



    return 0;
}

 

 

shmwrite.c : 写入共享内存

 

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

int main(int argc, char ** argv)
{
    if(argc != 2){
        puts("pathname");
        return 0;
    }
    int key = ftok(argv[1],0);
    int shmid = shmget(key,0,0664);
    printf("key:%d, shmid:%d\n",key,shmid);
    char *ptr= (char*)shmat(shmid,NULL,0);
    char *p = ptr;
    printf("ptr:%p\n", ptr);
    struct shmid_ds shmbuf;
    shmctl(shmid,IPC_STAT,&shmbuf);
    printf("shm size:%ld\n",shmbuf.shm_segsz);
    for(int i =0 ; i < shmbuf.shm_segsz;++i)
        *p++ = i;
    shmdt(ptr);


    return 0;
}

 

 

shmread.c : 读取共享内存

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

int main(int argc, char ** argv)
{
    if(argc != 2){
        puts("pathname");
        return 0;
    }
    int key = ftok(argv[1],0);
    int shmid = shmget(key,0,0664);
    char *ptr = (char*)shmat(shmid,NULL,0);
    char *p = ptr;
    struct shmid_ds shmbuf;
    shmctl(shmid,IPC_STAT,&shmbuf);
    printf("shm size :%ld\n",shmbuf.shm_segsz);

    for(int i = 0 ; i < shmbuf.shm_segsz;++i)
        printf("%c ",*p++);
    puts("");
    shmdt(ptr);

    return 0;
}

 

 

Posix :

shm_open.c

#include <stdio.h>
#include <unistd.h>
#include <sys/shm.h>
#include <sys/ipc.h>
#include <stdlib.h>
#include <sys/mman.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <fcntl.h>

int main(int argc , char ** argv , char ** env)
{
    if(argc !=3){
        printf("shm_open  path size ?\n");
        return 0;
    }

    int flags = O_RDWR|O_CREAT;
    int size = atoi(argv[2]);
    int shmfd = shm_open(argv[1],flags,0664);
    printf("shmfd :%d\n",shmfd);
    ftruncate(shmfd,size);

    struct stat stat;
    fstat(shmfd,&stat);
    printf("shm size:%ld\n" , stat.st_size);
    char * ptr = (char*)mmap(NULL,size,PROT_WRITE|PROT_READ,MAP_SHARED,
            shmfd,0);
    printf("mmap :%p\n" , ptr);


    return 0;
}

 

shm_unlink.c

#include <stdio.h>
#include <unistd.h>
#include <sys/shm.h>
#include <sys/ipc.h>
#include <stdlib.h>
#include <sys/mman.h>
#include <sys/stat.h>
#include <fcntl.h>

int main(int argc , char ** argv , char ** env)
{
    if(argc !=2){
        puts("shm_unlink path");
        return 0;
    }
    shm_unlink(argv[1]);


    return 0;
}

 

 

shm_write.c

#include <stdio.h>
#include <unistd.h>
#include <sys/shm.h>
#include <sys/ipc.h>
#include <stdlib.h>
#include <sys/mman.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <fcntl.h>

int main(int argc , char ** argv , char ** env)
{

    if(argc != 2){
        puts("shm_write path");
        return 0;
    }
    int shmfd = shm_open(argv[1],O_RDWR,0664);
    printf("shmid : %d\n" , shmfd);
    struct stat stat;
    fstat(shmfd,&stat);
    printf("shm size : %ld\n" , stat.st_size);
    char * ptr = mmap(NULL,stat.st_size,PROT_READ|PROT_WRITE,MAP_SHARED,
    shmfd,0);
    close(shmfd);

    char * p = ptr;
    for(int i = 0; i < stat.st_size; ++i)
        *p++ = i;

    return 0;
}

 

 

shm_read.c

#include <stdio.h>
#include <unistd.h>
#include <sys/shm.h>
#include <sys/ipc.h>
#include <stdlib.h>
#include <sys/mman.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <fcntl.h>

int main(int argc , char ** argv , char ** env)
{
    if(argc != 2){
        puts("shm_read path");
        return 0;
    }
    int shmfd = shm_open(argv[1],O_RDWR,0664);
    struct stat stat;
    fstat(shmfd,&stat);
    char * ptr = (char*)mmap(NULL,stat.st_size,PROT_READ,MAP_SHARED,shmfd,0);

    char * p = ptr;
    for(int i =0 ; i < stat.st_size;++i)
        printf("%c " ,*p++);
    puts("");
    close(shmfd);


    return 0;
}

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值