共享內存基本操做

共享內存使用的函數介紹html

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);ui

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

int shmdt(const void *shm_addr);spa

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

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

shmid_ds結構至少包含如下成員:unix

struct shmid_ds {指針

  uid_t shm_perm.uid;code

  uid_t shm_perm.gid;htm

  mode_t shm_perm.mode;blog

}

參數:
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 $@
clean:
        rm -f *.o $(bin)

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

相關文章
相關標籤/搜索