在讀apue的時候,共享存儲區的講解並沒用實例,為此自己寫了一個小程序,程序粗創建子進程,由子進程從終端接收字符串存入共享區,
父進程從共享區讀出字符串並輸出。同時,父子進程均輸出各自的共享區的地址區間區間。
#include "apue.h"
2. #include <sys/shm.h>
3. #define SHM_SIZE 100000//共享存儲區長度
4. #define SHM_MODE 0600//共享存儲區默認訪問權限
5. int
6. main(void)
7. {
8. int shmid,pid;
9. char* shmptr;
10. key_t key;
11. if(key=ftok("sharem.c",1)==-1) //使用ftok創建相應的key
12. printf("ftok error\n");
13. if((shmid=shmget(key,SHM_SIZE,IPC_CREAT|SHM_MODE))==-1)
14. printf("shmget error\n");
15. if((pid=fork())<0)
16. printf("fork error\n");
17. else if(pid==0)//子進程,從終端接收字符串存入共享存儲區
18. {
19. if((shmptr=shmat(shmid,0,0))==(void*)-1)
20. printf("child shmat error\n");
21. printf("child share memory attached from %lx to %lx\n",(unsigned long)shmptr,(unsigned long)shmptr+SHM_SIZE);//輸出共享存儲區在子進程中的地址區間
22. printf("child input:");
23. scanf("%s",shmptr);
24. exit(0);
25. }
26. else//父進程,從共享存儲區讀出字符串輸出到終端
27. {
28. sleep(5);
29. if((shmptr=shmat(shmid,0,0))==(void*)-1)
30. printf("parent shmat error\n");
31. printf("parent share memory attached from %lx to %lx\n",(unsigned long)shmptr,(unsigned long)shmptr+SHM_SIZE);//輸出共享存儲區在父進程中的地址區間
32. printf("parent output:");
33. printf("%s\n",shmptr);
34. }
35. exit(0);
36. }
37. //注:本程序為了是程序簡潔,並沒有采用信號量或者記錄鎖來保證共享區的同步訪問,而是采用讓父進程等待5秒鐘來保證子進程先執行。
運行結果:
分析:共結果可發現,父子進程的共享區區間地址相同,根據apue的說明,此處可能使用了“匿名存儲映射”技術,但是不能認為共享存儲區在不同的進程中地址都相同,這僅是在父子進程中。在不同進程中,可能將共享區
連接到不同的地址,所以當在共享區中存入指針類型時,絕不會存放實際物理地址,相反,指針值設置為段內另一對象的偏移量,偏移量為所指對象的實際地址減去共享存儲區的起始地址。
另外:通過執行ipcs命令可以發現,當程序結束後,共享存儲區依然還在。