《邊干邊學》上一個簡單的共享內存的例程:


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

#define?KEY?1234
#define?SIZE?1024

int?main()


{
????int?shmid;
????char?*shmaddr;
????struct?shmid_ds?buf;

????shmid?=?shmget(KEY,?SIZE,?IPC_CREAT?|?0600);

????if?(shmid?==?-1)?
{
????????printf("Failed?in?creating?shared?memory:?%s\n",?strerror(errno));
????????return?0;
????}


????if?(fork()?==?0)?
{
????????shmaddr?=?(char?*)?shmat(shmid,?NULL,?0);


????????if?(shmaddr?==?(void?*)?-1)?
{
????????????printf("Failed?in?connecting?to?the?shared?memory:?%s\n",?strerror(errno));
????????????return?0;
????????}
????????
????????strcpy(shmaddr,?"Hello,?this?is?child?process!\n");
????????shmdt(shmaddr);
????????return?0;

????}?else?
{
????????sleep(3);
????????shmctl(shmid,?IPC_STAT,?&buf);
????????
????????printf("Size?of?the?shared?memory:?");
????????printf("shm_segsz?=?%d?bytes\n",?buf.shm_segsz);
????????printf("Process?id?of?the?creator:?");
????????printf("shm_cpid?=?%d\n",?buf.shm_cpid);
????????printf("Process?id?of?the?last?operator:?");
????????printf("shm_lpid?=?%d\n",?buf.shm_lpid);

????????shmaddr?=?(char?*)?shmat(shmid,?NULL,?0);


????????if?(shmaddr?==?(void?*)?-1)?
{
????????????printf("Failed?in?connecting?the?shared?memory:?%s\n",?strerror(errno));
????????????return?0;
????????}

????????printf("The?content?of?the?shared?memory:?%s\n",?shmaddr);

????????shmdt(shmaddr);
????????shmctl(shmid,?IPC_RMID,?NULL);
????}
}
主要的API:
shmget 創建一塊共享內存
shmat 將一塊已經存在的共享內存映射到一個進程的地址空間
shmdt 取消一個進程的地址空間中的一塊共享塊的映射
shmctl 管理共享內存,和ioctl的風格很像
每一個新創建的共享都由一個shmid_ds{}表示。struct shmid_ds在linux/shm.h中的定義:



/**//*?Obsolete,?used?only?for?backwards?compatibility?and?libc5?compiles?*/

struct?shmid_ds?
{

????struct?ipc_perm????????shm_perm;????/**//*?operation?perms?*/

????int????????????shm_segsz;????/**//*?size?of?segment?(bytes)?*/

????__kernel_time_t????????shm_atime;????/**//*?last?attach?time?*/

????__kernel_time_t????????shm_dtime;????/**//*?last?detach?time?*/

????__kernel_time_t????????shm_ctime;????/**//*?last?change?time?*/

????__kernel_ipc_pid_t????shm_cpid;????/**//*?pid?of?creator?*/

????__kernel_ipc_pid_t????shm_lpid;????/**//*?pid?of?last?operator?*/

????unsigned?short????????shm_nattch;????/**//*?no.?of?current?attaches?*/

????unsigned?short?????????shm_unused;????/**//*?compatibility?*/

????void?????????????*shm_unused2;????/**//*?ditto?-?used?by?DIPC?*/

????void????????????*shm_unused3;????/**//*?unused?*/
};
其中存放權限信息的ipc_perm{}的定義為:
include/linux/ipc.h



/**//*?Obsolete,?used?only?for?backwards?compatibility?and?libc5?compiles?*/
struct?ipc_perm


{
????__kernel_key_t????key;
????__kernel_uid_t????uid;
????__kernel_gid_t????gid;
????__kernel_uid_t????cuid;
????__kernel_gid_t????cgid;
????__kernel_mode_t????mode;?
????unsigned?short????seq;
};








































































shmget 創建一塊共享內存
shmat 將一塊已經存在的共享內存映射到一個進程的地址空間
shmdt 取消一個進程的地址空間中的一塊共享塊的映射
shmctl 管理共享內存,和ioctl的風格很像
每一個新創建的共享都由一個shmid_ds{}表示。struct shmid_ds在linux/shm.h中的定義:






























其中存放權限信息的ipc_perm{}的定義為:
include/linux/ipc.h
















mode為該共享的內存的讀寫權限,和chmod的參數有點像。mode低九位定義了訪問許可,解釋如下:
0400?用戶可讀? 0200用戶可寫? 0040 組成員可讀? 0020 組成員可寫? 0004 其他用戶可讀??0002 其他用戶可寫
沒有執行位 0100 0010 和 0001
?