共享內存


共享內存:

特點:

  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