shared memory on linux
實作function有shmget和mmap
而shmget主要的function有
shmget()
shmat()
shmdt()
shmctl()
refer
http://baike.baidu.com/view/3838033.htm
http://blog.csdn.net/wlh_flame/article/details/6328380
…
shmget()
用來得到一個shared memory id或建立一個shared memory object。
格式如下
shmget(key_t key, size_t size, int shmflg)
參數說明如下
Key:0表示建立新的shared memory object,>0表示根據shmflag的值操作。
Size:0表示只取得share memory,>0則表示要指定的shared memory大小。
shmflag:使用IPC_CREAT時,若沒有shared memory object則建立一個,若有則回傳shared memory id。
ex:
shm_id=shmget(key,0, 0);
shm_id=shmget(key,4096,IPC_CREAT|IPC_EXCL|0600)
shm_id=shmget(SHMKEY, MAXBUF+1, 0666)
shm_id=shmget(SHMKEY, MAXBUF+1, IPC_CREAT | 0666)
refer
http://man7.org/linux/man-pages/man2/shmget.2.html
shmat()
透過shmget()產生的shared memory id將shared memory object映射到memory,之後會回傳可直接存取的shared memory address。
格式如下
shmat(int shmid, const void *shmaddr, int shmflg)
參數說明如下
shmid:使用那一個shared memory id。
shmaddr:指定shared memory要出現的位置,直接指定null可讓作業系統自己決定。
shmflag:直接使用0即可。
ex:
shm = shmat(shm_id, NULL, 0)
shm =(people*)shmat(shm_id,NULL,0)
refer
http://man7.org/linux/man-pages/man2/shmat.2.html
shmdt()
將shared memory的address關閉,成功會傳回0
格式如下
shmdt(const void *shmaddr)
參數說明如下
shmaddr:shared memory的address
ex:
shmdt(shm);
refer
http://man7.org/linux/man-pages/man2/shmdt.2.html
shmctl()
管理shared memory
格式如下
shmctl(int shmid, int cmd, struct shmid_ds *buf)
參數說明如下
cmd:有以下三種參數可選
IPC_STAT:得到shared memory的狀態
IPC_SET:改變shared memory的狀態
IPC_RMID:刪除shared memory
buf:shared memory結構
ex:
shmctl(shmid, IPC_RMID, NULL);
refer
http://man7.org/linux/man-pages/man2/shmctl.2.html
…………………………………………………………………………………………………………………………..
shared memory在linux常用的指令
顯示目前的Shared Memory Segments
#ipcs -m
—— Shared Memory Segments ——–
key shmid owner perms bytes nattch status
0x50494f4e 0 nobody 666 2016 1
0x000004d2 2064385 root 666 1025 0
刪除指定的Shared Memory Segments
#ipcrm -m < shmid>
ex:
删除key=0x000004d2 shmid=2064385的共享内存
#ipcrm -m 2064385
………………………………………………………………………………………………………………………….
以shared memory實作簡易聊天程式範例
執行方式為
#chat < username>
#vi chat.c
程式碼如下
#include < sys/types.h>
#include < sys/ipc.h>
#include < sys/shm.h>
#include < stdio.h>
#include < stdlib.h>
#include < string.h>
#include < unistd.h>
#define PERMS 0666
#define SHMKEY ((key_t) 1234)
#define MAXBUF 2048
int inputchat(char *username){
int shmid, str_len;
key_t key;
char *shm;
char str_buf[MAXBUF]="";
char str2_buf[MAXBUF]="";
char speaker[100];
if ((shmid = shmget(SHMKEY, MAXBUF+1, PERMS)) < 0) {
perror("shmget");
exit(1);
}
if ((shm = shmat(shmid, NULL, 0)) == (char *) -1) {
perror("shmat");
exit(1);
}
strcpy(speaker,username);
strcat(speaker,":");
printf("Hello %s, Enter Words: n",username);
while (1) {
strcpy(str_buf, "");
fgets(str_buf,2000, stdin);
strncpy(str2_buf,speaker,30);
strcat(str2_buf,str_buf);
str_len = strlen(str2_buf);
strcpy(shm,str2_buf);
}
}
int outputchat(){
int shmid;
key_t key;
char *shm, *s;
if ((shmid = shmget(SHMKEY, MAXBUF+1, IPC_CREAT | PERMS)) < 0) {
perror("shmget");
exit(1);
}
if ((shm = shmat(shmid, NULL, 0)) == (char *) -1) {
perror("shmat");
exit(1);
}
while(1){
shm[MAXBUF] = 1;
while(strstr(shm, "n") == NULL){
if(shm[MAXBUF] == 1){
continue;
}
}
printf("%s ", shm);
sleep(1);
strcpy(shm,"");
}
}
int main(int argc, char **argv){
pid_t fpid;
fpid=fork();
if(fpid < 0)
printf("error in fork!");
else if (fpid == 0) {
outputchat();
}else {
inputchat(argv[1]);
}
return 0;
}