XSI IPC之共享內(nèi)存 (1)

有兩種方法創(chuàng)建共享內(nèi)存,第一種用shmop提供的函數(shù),第二種通過(guò)mmap(2)函數(shù)

man shmop 查看共享內(nèi)存操作函數(shù)

shmget( )

獲得一個(gè)共享存儲(chǔ)標(biāo)識(shí)符

函數(shù)聲明

#include <sys/ipc.h>
#include <sys/shm.h>

int shmget(key_t key, size_t size, int shmflg);

參數(shù)含義

第一個(gè)參數(shù)為ftok(3)函數(shù)返回值,如果 key值為 IPC_PRIVATE 則只能用于有親緣關(guān)系

第二個(gè)參數(shù)為共享內(nèi)存空間的大小

第三個(gè)參數(shù)可選(多選用或運(yùn)算)

IPC_CREAT 創(chuàng)建,需要或上文件權(quán)限

IPC_EXCLIPC_CREAT一起使用,確保如果消息隊(duì)列已經(jīng)創(chuàng)建,則返回失敗

返回值

成功返回 共享內(nèi)存示例

失敗返回 -1 并且設(shè)置errno 如果標(biāo)識(shí)符使用了IPC_CREATIPC_EXCL 并且errno的值為EEXIST,代表消息隊(duì)列已經(jīng)存在

shmat()

掛載共享內(nèi)存,將共享內(nèi)存連接到進(jìn)程的可用地址上

函數(shù)聲明

#include <sys/types.h>
#include <sys/shm.h>

void *shmat(int shmid, const void *shmaddr, int shmflg);

參數(shù)含義

第一個(gè)參數(shù)為共享內(nèi)存示例

第二個(gè)參數(shù)如果是NULL,則內(nèi)核自動(dòng)分配到進(jìn)程所在的第一個(gè)可用地址上,不傳NULL,則分配地址由用戶指定;

返回值

成功返回共享內(nèi)存地址,失敗返回-1,設(shè)置errno值

shmdt()

卸載共享內(nèi)存,將共享內(nèi)存從進(jìn)程的可用地址上刪除

函數(shù)聲明

#include <sys/types.h>
#include <sys/shm.h>

int shmdt(const void *shmaddr);

參數(shù)含義

shmaddr為shmdt函數(shù)的返回值

shmctl()

移除共享內(nèi)存

函數(shù)聲明

#include <sys/ipc.h>
#include <sys/shm.h>

int shmctl(int shmid, int cmd, struct shmid_ds *buf);

共享內(nèi)存示例1

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

int main(void)
{
    pid_t pid;
    int shmid;
    int flag = 1;

    shmid = shmget(IPC_PRIVATE, 1024, IPC_CREAT | IPC_EXCL | 0600);
    if (shmid < 0) {
        if (errno == EEXIST) {
            shmid = shmget(IPC_PRIVATE, 1024, 0);
            flag = 0;
        } else {
            perror("shmid()");
            exit(1);
        }
    }

    pid = fork();
    if (pid < 0) {
        perror("fork()");
        goto FORK_ERROR;
    }

    if (pid == 0) {
        void *p = shmat(shmid, NULL, 0);    
        memcpy(p, "hello world", 11);
        shmdt(p);
        exit(1);
    }

    wait(NULL);
    void *ptr = shmat(shmid, NULL, 0);
    puts((char *)ptr);
    shmdt(ptr);

    if (flag)
        shmctl(shmid, IPC_RMID, NULL);
    exit(0);
FORK_ERROR:
    if (flag)
        shmctl(shmid, IPC_RMID, NULL);
    exit(1);
}
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容