1. 程式人生 > >Linux共享記憶體與互斥鎖

Linux共享記憶體與互斥鎖

Linux共享記憶體

共享記憶體是從系統的空閒記憶體池中分配,並希望訪問它的每個程序都能連線它。連線的過程稱為對映。對映後,每個程序都可通過訪問自己的記憶體而訪問共享記憶體區域,進而與其它程序進行通訊。

共享記憶體相關函式

  • 開啟建立共享記憶體檔案

int shm_open(const char *name, int oflag, mode_t mode)

  • 刪除共享記憶體

int shm_unlink(const char *name)

  • 重置共享記憶體檔案大小

int ftruncate(int fd, off_t length)

  • 建立(連線)共享記憶體對映

void *mmap(void *addr, size_t length, int prot, int flags, int fd, off_t offset)

// addr:建立對映區的首地址,由Linux核心指定。使用是,直接傳遞NULL

// length:欲建立對映區的大小

// prot:對映區許可權PROT_READ、PROT_WRITE、PROT_READ|PROT_WRITE

// flags:標誌位引數(常用於設定更新物理區域,設定共享、建立匿名對映區)

       MAP_SHARED:會將對映區所做的操作反映到物理裝置(磁碟上),無血緣關係的程序通訊

       MAP_PRIVATE:對映區所做的修改不會反映到物理裝置

       MAP_ANONYMOUS:匿名對映區

// fd:用來建立對映區的檔案描述符

// offset:對映檔案的偏移(4k的整數倍)

  • 解除對映

int munmap(void *addr, size_t length)

程序間同步互斥鎖相關函式

  • 初始化互斥鎖

int pthread_mutex_init(pthread_mutex_t *mutex, const pthread_mutexattr_t *mutexattr)

  • 釋放互斥鎖

int pthread_mutex_destroy(pthread_mutex_t *mutex)

  • 嘗試加鎖

int pthread_mutex_trylock(pthread_mutex_t *mutex)

  • 加鎖

int pthread_mutex_lock(pthread_mutex_t *mutex)

  • 加鎖(存在時間限制)

int pthread_mutex_timedlock(pthread_mutex_t *restrict mutex, const struct timespc *restrict abstime)

  • 解鎖

int pthread_mutex_unlock(pthread_mutex_t *mutex)

  • 定義mutex鎖的屬性

pthread_mutexattr_t mattr

  • 初始化一個mutex屬性物件

int pthread_mutexattr_init(pthread_mutexattr_t *attr)

  • 銷燬mutex屬性物件(非銷燬鎖)

int pthread_mutexattr_destory(pthread_mutexattr_t *attr)

  • 修改mutex屬性

int pthread_mutexattr_setshared(pthread_mutexattr *attr, int pshared)

// pshared取值如下:

// 執行緒鎖:PTHREAD_PROCESS_PRIVATE(mutex的預設屬性為執行緒鎖,程序間私有)

// 程序鎖:PTHREAD_PROCESS_SHARED

共享記憶體測試程式

// test1.cpp
#include <stdio.h>
#include <stdlib.h>
#include <sys/mman.h>
#include <string.h>
#include <fcntl.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <unistd.h>

int main() {
        int fd = shm_open("/test-shm", O_CREAT|O_RDWR|O_EXCL, 0777);
        if (fd < 0) {
                fd = shm_open("/test-shm", O_RDWR, 0777);
                printf("open ok\n");
                if (fd < 0) {
                        printf("error open shm object\n");
                        return 0;
                }  
        }  
        else {
                printf("create ok\n");
                ftruncate(fd, 1024);
        }
        char *ptr = (char *)mmap(NULL, 1024, PROT_READ|PROT_WRITE, MAP_SHARED, fd, 0);
        close(fd);
        strcpy(ptr, "write by t08");
        return 0;
}

程式編譯:

gcc -lrt -o test1 test1.cpp

// test2.cpp
#include <stdio.h>
#include <stdlib.h>
#include <sys/mman.h>
#include <string.h>
#include <fcntl.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <unistd.h>

int main() {
        int fd = shm_open("/test-shm", O_RDWR, 0777);
        if (fd < 0) {
                printf("error open shm object\n");
                return 0;
        }  
        char *ptr = (char *)mmap(NULL, 1024, PROT_READ|PROT_WRITE, MAP_SHARED, fd, 0);
        close(fd);
        getchar();
        printf("%s\n", ptr);
        return 0;
}

程式編譯:

gcc -lrt -o test2 test2.cpp

程式執行:

./test1和./test2後,能看到相關結果