shmctl( shmid , IPC_STAT , &buf ); // 取得share mem的狀態
shmctl( shmid , IPC_RMID , &buf ); // 删除share mem
注意!!!!!!!!!:在使用share memory時,结束程式退出後。如果没在程式中用 IPC_RMID删除 share memory 的話,用指令ipcs可看到ipc的三個狀態(share memory、semaphore、message queue)
可用ipcrm指令删除刪除。要是不管的話,會佔用系統資源。
ref:
激情、专注、坚持、思考
2012年1月20日 星期五
2012年1月19日 星期四
Share memory 基本流程
ftok:取得key (有其bug,使用要小心)
shmget:指定key,mem大小,回傳id。同個key就不需再開個mem
shmat:掛戴(attach)到mem,process才能使用
shmdt:卸載(detach)
shmctl:要detach後才能刪除(IPC_RMID)
shmget:指定key,mem大小,回傳id。同個key就不需再開個mem
shmat:掛戴(attach)到mem,process才能使用
shmdt:卸載(detach)
shmctl:要detach後才能刪除(IPC_RMID)
2012年1月18日 星期三
Share memory / Semaphore 之一
【轉貼】汐っ阳的嵌入式博客 /* * 共享内存 * 信号量控制共享内存的同步,实现父子进程通信, * 思路: 第一步,创建信号量,映像共享内存 第二步,创建子进程,让子进程继承父进程所有上下文 第三步,父进程睡眠一秒,让子进程获得CPU时间 第四步,子进程运行,立刻进行P操作 第五步,子进程睡眠4秒,主动放弃CPU 第六步,父进程获得CPU,但信号量已为0,无法进行P操作,只能继续打酱油,父进程被阻塞 第七步,子进程接着运行,最后释放共享内存,进行V操作, 第八步,父进程被换醒,获得信号锁,运行,最后,删除共享内存,退出程序 * Lzy 2011-6-16 */ #include <stdio.h> #include <stdlib.h> #include <sys/ipc.h> #include <sys/shm.h> #include <sys/types.h> #include <unistd.h> #include <string.h> #include <sys/sem.h> #define SHM_SIZE 1024 //共享内存的大小 int main(void) { int ret, //临时变量 pid, //进程id sme_id, //保存信号量描述符 shm_id; //保存共享内存描述符 key_t sme_key, //保存信号量键值 shm_key; //保存共享内存键值 char *shmp; //指向共享内存的首地址 struct shmid_ds dsbuf; //定义共享内存信息结构变量 struct sembuf lock = {0, -1, SEM_UNDO}; //信号量上锁操作的数组指针 struct sembuf unlock = {0, 1, SEM_UNDO | IPC_NOWAIT};//信号量解锁操作的数组指针 sme_key = ftok("/dev/shm/t2", 2); //获取信号量键值 if(sme_key < 0) { perror("ftok"); exit(0); } sme_id = semget(sme_key, 1, IPC_CREAT | 0666); //获取信号量ID if(sme_id < 0) { perror("semget"); exit(0); } shm_key = ftok("/dev/shm/t2", 1); //获取共享内存键值,路徑要事先建好 if(shm_key < 0) { perror("ftok"); exit(0); } shm_id = shmget(shm_key, SHM_SIZE, IPC_CREAT | 0666); //获取共享内存ID if(shm_id < 0) { perror("shmget"); exit(0); } shmp = shmat(shm_id, NULL, 0); //映像共享内存 if((int)shmp == -1) { perror("shmat"); exit(0); } pid = fork(); //创建子进程 if(pid < 0) { perror("fork"); exit(0); } else if(pid == 0) //子进程 { ret = semctl(sme_id, 0, SETVAL, 1); //初始化信号量,初值设为1 (不懂其意 if(ret == -1) { perror("semctl"); exit(0); } ret = semop(sme_id, &lock, 1); //申请访问共享资源,锁定临界资源 if(ret == -1) { perror("semop lock--c"); exit(0); } sleep(4); //让子进程睡眠4秒 strcpy(shmp, "hello\n"); //往共享内存写入数据 if(shmdt((void *)shmp) < 0) //使共享内存脱离进程地址空间 { perror("shmdt"); } ret = semop(sme_id, &unlock, 1); //解锁临界资源 if(ret == -1) { perror("semop unlock--c2"); exit(0); } } else //父进程 sleep(1); //先让子进程运行 ret = semop(sme_id, &lock, 1); //申请访问共享资源,锁定临界资源 if(ret == -1) { perror("semop lock"); exit(0); } if(shmctl(shm_id, IPC_STAT, &dsbuf) < 0) //获取共享内存信息 { perror("shmctl"); exit(0); } else /* 共享内存的状态信息获取成功 */ { printf("Shared Memory Information:\n"); printf("\tCreator PID: %d\n", dsbuf.shm_cpid); /* 输出创建共享内存进程的标识符 */ printf("\tSize(bytes): %d\n",dsbuf.shm_segsz); /* 输出共享内存的大小 */ printf("\tLast Operator PID: %d\n",dsbuf.shm_lpid); /* 输出上一次操作共享内存进程的标识符 */ printf("Received message : %s\n", (char *)shmp); /* 从共享内存中读取数据 */ } if(shmdt((void *)shmp) < 0) //使共享内存脱离进程地址空间 { perror("shmdt"); exit(0); } ret = semop(sme_id, &unlock, 1); //解锁临界资源 if(ret == -1) { perror("semop unlock--p"); exit(0); } if(shmctl(shm_id, IPC_RMID, NULL) < 0) /* 删除前面创建的共享内存 */ { perror("shmctl"); exit(0); } ret = semctl(sme_id, 0, IPC_RMID, NULL); //删除信号量 if(ret == -1) { perror("semctl"); exit(0); } } return 0; } ref : 汐っ阳的嵌入式博客
2012年1月17日 星期二
ftok 注意事項
系統建立IPC通訊(如Message Queues、share memory時)必須指定一個ID值。通常情況下,該id值通過ftok函數得到。 ftok原型如下: key_t ftok( char * fname, int id ) fname就時你指定的文件名,id是子序號。 在一般的UNIX實現中,是將文件的索引節點號取出,前面加上子序號得到key_t的返回值。 如指定文件的索引節點號為65538,換算成16進制為0x010002,
而你指定的ID值為38,換算成16進制為0x26,則最後的key_t返回值為0x26010002。
查詢文件索引節點號的方法是: ls -i 當刪除重建文件後,索引節點號由操作系統根據當時文件系統的使用情況分配,因此與原來不同,所以得到的索引節點號也不同。 如果要確保key_t值不變,要嘛確保ftok的文件不被刪除,要嘛不用ftok,指定一個固定的key_t值。ref : Here
訂閱:
文章 (Atom)