1. 程式人生 > >共享內存基本操作

共享內存基本操作

not key 有用 private ddr wall 數據 reat note

共享內存使用的函數介紹

1. shmget函數 該函數用來創建共享內存:

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

參數: key : 和信號量一樣,程序需要提供一個參數key, 它有效地為共享內存段命名。 有一個特殊的鍵值IPC_PRIVATE, 它用於創建一個只屬於創建進程的共享內存, 通常不會用到。 size: 以字節為單位指定需要共享的內存容量。 shmflag: 包含9個比特的權限標誌, 它們的作用與創建文件時使用的mode標誌是一樣。 由IPC_CREAT定義的一個特殊比特必須和權限標誌按位或
才能創建一個新的共享內存段。 NOTE: 權限標誌對共享內存非常有用, 因為它允許一個進程創建的共享內存可以被共享內存的創建者所擁有的進程寫入, 同時其它用戶創建的進程只能讀取共享內存。 我們可以利用這個功能來提供一種有效的對數據進行只讀訪問的方法, 通過將數據放共享內存並設置它的權限, 就可以避免數據被其他用戶修改。 返回值: 創建成功,則返回一個非負整數,即共享內存標識; 如果失敗,則返回-1. 2. shmat函數 第一次創建共享內存段時,它不能被任何進程訪問。 要想啟動對該內存的訪問, 必須將其連接到一個進程的地址空間 這個工作由shmat函數完成:

void *shmat(int shm_id, const void *shm_addr, int shmflg);

參數: shm_id : 由shmget返回的共享內存標識。 shm_add: 指定共享內存連接到當前進程中的地址位置。 它通常是一個空指針, 表示讓系統來選擇共享內存出現的地址。 shmflg : 是一組標誌。 它的兩個可能取值是: SHM_RND, 和shm_add聯合使用, 用來控制共享內存連接的地址。 SHM_RDONLY, 它使連接的內存只讀
返回值: 如果調用成功, 返回一個指向共享內存第一個字節的指針; 如果失敗,返回-1. 共享內存的讀寫權限由它的屬主(共享內存的創建者), 它的訪問權限和當前進程的屬主決定。 共享內存的訪問權限類似於文件的訪問權限。 3. shmdt 將共享內存從當前進程中分離

int shmdt(const void *shm_addr);

shm_addr: shmat返回的地址指針。 成功時,返回0, 失敗時,返回-1. NOTE: 共享內存分離並未刪除它, 只是使得該共享內存對當前進程不再可用。 4. shmctl 共享內存的控制函數

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

shmid_ds結構至少包含以下成員:

struct shmid_ds {

uid_t shm_perm.uid;

uid_t shm_perm.gid;

mode_t shm_perm.mode;

}

參數: shm_id : 是shmget返回的共享內存標識符。 command: 是要采取的動作, 它可以取3個值: IPC_STAT 把shmid_ds結構中的數據設置為共享內存的當前關聯值 IPC_SET 如果進程有足夠的權限, 就把共享內存的當前關聯值設置為shmid_ds結構中給出的值 IPC_RMID 刪除共享內存段 buf : 是一個指針, 包含共享內存模式和訪問權限的結構。 返回值: 成功時,返回0, 失敗時,返回-1. 代碼實現 shmwrite.c
#include <stdio.h>
#include <stdlib.h>
#include <sys/ipc.h>
#include <sys/shm.h>
#include <string.h>

typedef struct stu
{
        char name[32];
        int age;
} STU;

int main(int argc, char *argv[])
{
        int shmid;
        shmid = shmget((key_t)1234,sizeof(STU),IPC_CREAT | 0666);
        if (shmid == -1)
        {
                printf("shmget failed\n");
                exit(1);
        }

        STU *p;
        p = shmat(shmid,NULL,0);
        if (p == (void*)-1)
        {
                printf("shmat failed\n");
                exit(1);
        }

        strcpy(p->name, "zhangsan");
        p->age = 20;

        while(1)
        {
                if(memcmp(p, "quit",4) == 0)
                {
                        break;
                }
        }

        shmdt(p);
        shmctl(shmid,IPC_RMID,NULL);

        return 0;
}

shmread.c

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

typedef struct stu
{
        char name[32];
        int age;
} STU;

int main(int argc, char *argv[])
{
        int shmid;
        shmid = shmget((key_t)1234,0,0);
        if (shmid == -1)
        {
                printf("shmget failed\n");
                exit(1);
        }

        STU *p;
        p = shmat(shmid,NULL,0);
        if (p == (void*)-1)
        {
                printf("shmat failed\n");
                exit(1);
        }

        printf("name = %s, age = %d\n",p->name,p->age);
        memcpy(p,"quit",4);

        shmdt(p);
        return 0;
}

Makefile

.PHONY: clean all
CC=gcc
CFLAGS=-Wall -g
BIN=shmwrite shmread
all:$(BIN)
%.o:%.c
        $(cc) $(CFLAGS) -c $< -o [email protected]
clean:
        rm -f *.o $(bin)

參考:http://blog.chinaunix.net/uid-26000296-id-3421346.html

共享內存基本操作