linux进程通信(四)–共享内存+信号量
1. /*server.c:向共享内存中写入People*/ 2. #include <stdio.h> 3. #include <sys/types.h> 4. #include <sys/ipc.h> 5. #include <sys/sem.h> 6. 7. int main() 8. { 9. struct People{ 10. char name[10]; 11. int age; 12. }; 13. 14. int semid; 15. int shmid; 16. key_t semkey; 17. key_t shmkey; 18. semkey=ftok("server.c",0); 19. shmkey=ftok("client.c",0); 20. 21. /*创建共享内存和信号量的IPC*/ 22. semid=semget(semkey,1,0666|IPC_CREAT); 23. if(semid==-1) 24. printf("creat sem is failn"); 25. shmid=shmget(shmkey,1024,0666|IPC_CREAT); 26. if(shmid==-1) 27. printf("creat shm is failn"); 28. 29. /*设置信号量的初始值,就是资源个数*/ 30. union semun{ 31. int val; 32. struct semid_ds *buf; 33. ushort *array; 34. }sem_u; 35. 36. sem_u.val=1; 37. semctl(semid,0,SETVAL,sem_u); 38. 39. /*将共享内存映射到当前进程的地址中,之后直接对进程中的地址addr操作就是对共享内存操作*/ 40. 41. struct People * addr; 42. addr=(struct People*)shmat(shmid,0,0); 43. if(addr==(struct People*)-1) 44. printf("shm shmat is failn"); 45. 46. /*信号量的P操作*/ 47. void p() 48. { 49. struct sembuf sem_p; 50. sem_p.sem_num=0; 51. sem_p.sem_op=-1; 52. if(semop(semid,&sem_p,1)==-1) 53. printf("p operation is failn"); 54. } 55. 56. /*信号量的V操作*/ 57. void v() 58. { 59. struct sembuf sem_v; 60. sem_v.sem_num=0; 61. sem_v.sem_op=1; 62. if(semop(semid,&sem_v,1)==-1) 63. printf("v operation is failn"); 64. } 65. 66. /*向共享内存写入数据*/ 67. p(); 68. strcpy((*addr).name,"xiaoming"); 69. /* 注意:①此处只能给指针指向的地址直接赋值,不能在定义一个 struct People people_1;addr=&people_1; 因为addr在addr=(struct People*)shmat(shmid,0,0);时,已经由系统自动分配了一个地址,这个地址与共享内存相关联,所以不能改变这个指针的指向,否则他将不指向共享内存,无法完成通信了。 70. 注意:②给字符数组赋值的方法。刚才太虎了。。*/ 71. (*addr).age=10; 72. v(); 73. 74. /*将共享内存与当前进程断开*/ 75. if(shmdt(addr)==-1) 76. printf("shmdt is failn"); 77. 78. }
1. /*client.c:从共享内存中读出People*/
2. #include <stdio.h>
3. #include <sys/types.h>
4. #include <sys/ipc.h>
5. #include <sys/sem.h>
6.
7. int main()
8. {
9. int semid;
10. int shmid;
11. key_t semkey;
12. key_t shmkey;
13. semkey=ftok("server.c",0);
14. shmkey=ftok("client.c",0);
15.
16. struct People{
17. char name[10];
18. int age;
19. };
20.
21. /*读取共享内存和信号量的IPC*/
22. semid=semget(semkey,0,0666);
23. if(semid==-1)
24. printf("creat sem is failn");
25. shmid=shmget(shmkey,0,0666);
26. if(shmid==-1)
27. printf("creat shm is failn");
28.
29. /*将共享内存映射到当前进程的地址中,之后直接对进程中的地址addr操作就是对共享内存操作*/
30. struct People * addr;
31. addr=(struct People*)shmat(shmid,0,0);
32. if(addr==(struct People*)-1)
33. printf("shm shmat is failn");
34.
35. /*信号量的P操作*/
36. void p()
37. {
38. struct sembuf sem_p;
39. sem_p.sem_num=0;
40. sem_p.sem_op=-1;
41. if(semop(semid,&sem_p,1)==-1)
42. printf("p operation is failn");
43. }
44.
45. /*信号量的V操作*/
46. void v()
47. {
48. struct sembuf sem_v;
49. sem_v.sem_num=0;
50. sem_v.sem_op=1;
51.