1. 程式人生 > 實用技巧 >POSIX之共享記憶體

POSIX之共享記憶體

shm_write.c:

#include<stdio.h>
#include<stdlib.h>
#include <stdlib.h> 
#include <unistd.h>
#include <sys/file.h>
#include <sys/mman.h> 
#include <sys/wait.h>
void p_error(const char* str)
{
    perror(str);
    exit(1);
}
int main(int argc,char* argv[])
{
    
int ret; size_t mem_size = sysconf(_SC_PAGE_SIZE); int fd=shm_open("/mymen", O_CREAT|O_TRUNC|O_RDWR,0666); if(fd==-1) { perror("建立共享記憶體失敗\n"); } printf("建立共享記憶體成功\n"); //第二個引數用來指定擷取共享記憶體空間大小 ftruncate(fd,mem_size); void* ptr=mmap(0,mem_size,PROT_READ|PROT_WRITE, MAP_SHARED, fd, 0
); /* //第一個引數為0表示系統會自動尋找空閒空間作為開始地址 //void* mmap(void* start,size_t length,int prot,int flags,int fd,off_t offset); flags: 指定對映物件的型別,對映選項和對映頁是否可以共享。 它的值可以是一個或者多個以下位的組合 體 MAP_SHARED 與其它所有對映這個物件的程序共享對映空間。 對共享區的寫入,相當於輸出到文 件。 直到msync()或者munmap()被呼叫,檔案實際上不會被更新。 MAP_PRIVATE 建立一個寫入時拷貝的私有對映。記憶體區域的寫入不會影響到原檔案。 這個標誌和以 上標誌是互斥的,只能使用其中一個。 MAP_LOCKED 鎖定對映區的頁面,從而防止頁面被交換出記憶體。
*/ //成功返回共享記憶體地址,失敗返回MAP_FAILED if (ptr == MAP_FAILED) { p_error("記憶體對映失敗\n"); } close(fd); int i=0; while(i<10) { sprintf((char*)ptr,"data%d",i++); printf("寫入的資料為:%s\n",(char*)ptr); sleep(1); } ret = munmap(ptr, mem_size); //解除安裝共享記憶體 if (ret != 0) { p_error("解除安裝記憶體失敗"); } // ret = shm_unlink("/mymen"); // if (ret != 0) // { // p_error("刪除共享記憶體"); // } return 0; }

shm_read.c:

#include<stdio.h>
#include<stdlib.h>
#include <stdlib.h> 
#include <unistd.h>
#include <sys/file.h>
#include <sys/mman.h> 
#include <sys/wait.h>
void p_error(const char* str)
{
    perror(str);
    exit(1);
}
int main(int argc,char* argv[])
{
    int ret;
    size_t mem_size = sysconf(_SC_PAGE_SIZE);
    int fd=shm_open("/mymen",O_RDONLY,0666);
    if(fd==-1)
    {
        perror("建立共享記憶體失敗\n");
    } 
    printf("建立共享記憶體成功\n");

    ftruncate(fd,mem_size);

    void* ptr=mmap(0,mem_size,PROT_READ, MAP_SHARED, fd, 0);
    if (ptr == MAP_FAILED) 
    {
        p_error("記憶體對映失敗\n");
    }

    close(fd);

while(ptr++)
{
        printf("讀出的資料為:%s\n",(char*)ptr);
        sleep(1);
}
    
ret = munmap(ptr, mem_size); //解除安裝共享記憶體
if (ret != 0)
 {
     p_error("解除安裝記憶體失敗");
 }
 ret = shm_unlink("/mymen");
  if (ret != 0) 
{
    p_error("刪除共享記憶體");
} 


    return 0;
}