共享内存


共享内存:

特点:

  1、共享内存是一种最为高效的进程间通信方式,进程可以直接读写内存,而不需要任何数据的拷贝

  2、为了在多个进程间交换信息,内核专门留出了一块内存区,可以由需要访问的进程将其映射到自己的私有地址空间

  3、进程就可以直接读写这一内存区而不需要进行数据的拷贝,从而大大提高的效率。

  4、由于多个进程共享一段内存,因此也需要依靠某种同步机制,如互斥锁和信号量等

实现步骤:

主要函数:

1、 ftok(任意路径,任意0-255之间的数);//利用ftok函数获得一个key值

2、shmget(key值,空间大小,权限:例0666 | IPC_CREAT);//创建并打开共享内存创建共享内存:

 

3、char *p = (char *)shmat(shmID,NULL,0);//映射到用户空间。

4、shmdt (p);//撤销共享内存

5、shmctl(shmID,IPC_RMID,NULL);//删除共享内存

案例:

qy.c:

#include <stdio.h>
#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/shm.h>
#include <semaphore.h>
#include <fcntl.h>



int main(void)
{    
    //有名信号量的创建
    sem_t* sem_1 = sem_open("sem1", O_CREAT | O_RDONLY, 0666, 1);
    if(SEM_FAILED == sem_1)
    {
        perror("sem_open error");
        return -1;
    }
    sem_t* sem_2 = sem_open("sem2", O_CREAT | O_RDONLY, 0666, 0);
    if(SEM_FAILED == sem_2)
    {
        perror("sem_open error");
        return -1;
    }
    
    //获得一个Key值
    key_t key = ftok("./",10);
    //创建共享内存,返回一个内存ID
    int shmID = shmget(key, 200, 0666 | IPC_CREAT);
    if(-1 == shmID)
    {
        perror("shmget error");
        return -1;
    }
    //映射到用户空间返回空间地址
    char *p = (char *)shmat(shmID, NULL, 0);
    if((void *)-1 == (void *)p)
    {
        perror("shmat error");
        return -1;
    }
    //信号量的用法与无名相同
    sem_wait(sem_2);
    printf("%s\n",p);
    sem_post(sem_1);
    //删除信号量
    sem_unlink(sem_1);
    sem_unlink(sem_2);
    //撤销映射
    shmdt(p);
    //删除共享内存
    shmctl(shmID, IPC_RMID, NULL);
    return 0;    
}

wf.c

#include <stdio.h>
#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/shm.h>
#include <semaphore.h>
#include <fcntl.h>



int main(void)
{
    //有名信号量的创建
    sem_t* sem_1 = sem_open("sem1", O_CREAT | O_RDONLY, 0666, 1);
    if(SEM_FAILED == sem_1)
    {
        perror("sem_open error");
        return -1;
    }
    sem_t* sem_2 = sem_open("sem2", O_CREAT | O_RDONLY, 0666, 0);
    if(SEM_FAILED == sem_2)
    {
        perror("sem_open error");
        return -1;
    }
    //获得一个Key值
    key_t key = ftok("./",10);
    //创建共享内存,返回一个内存ID
    int shmID = shmget(key, 200, 0666 | IPC_CREAT);
    if(-1 == shmID)
    {
        perror("shmget error");
        return -1;
    }
    //映射到用户空间返回空间地址
    char *p = (char *)shmat(shmID, NULL, 0);
    if((void *)-1 == (void *)p)
    {
        perror("shmat error");
        return -1;
    }
    //信号量的用法与无名相同
    sem_wait(sem_1);
    printf("请输入:");
    gets(p);
    sem_post(sem_2);
   //关闭信号量文件
    sem_close(sem_1);
    sem_close(sem_2);
    //撤销映射
    shmdt(p);
    //删除共享内存
    shmctl(shmID, IPC_RMID, NULL);
    return 0;    
}

 

makefile

APP:
    gcc qy.c -o qy -lpthread
    gcc wf.c -o wf -lpthread

注意:这里清空共享内存空间可以用memset();

在终端输入ipcs -m 查看shmid

然后输入ipcrm -m ID号  及删除共享内存


免责声明!

本站转载的文章为个人学习借鉴使用,本站对版权不负任何法律责任。如果侵犯了您的隐私权益,请联系本站邮箱yoyou2525@163.com删除。



 
粤ICP备18138465号  © 2018-2025 CODEPRJ.COM