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 fail\n");
25. shmid=shmget(shmkey,1024,0666|IPC_CREAT);
26. if(shmid==-1)
27. printf("creat shm is fail\n");
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 fail\n");
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 fail\n");
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 fail\n");
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 fail\n");
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 fail\n");
25. shmid=shmget(shmkey,0,0666);
26. if(shmid==-1)
27. printf("creat shm is fail\n");
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 fail\n");
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 fail\n");
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. if(semop(semid,&sem_v,1)==-1)
52. printf("v operation is fail\n");
53. }
54.
55. /*从共享内存读出数据*/
56. p();
57. printf("name:%s\n",addr->name);
58. printf("age:%d\n",addr->age);
59. v();
60.
61. /*将共享内存与当前进程断开*/
62. if(shmdt(addr)==-1)
63. printf("shmdt is fail\n");
64.
65. /*IPC必须显示删除。否则会一直留存在系统中*/
66. if(semctl(semid,0,IPC_RMID,0)==-1)
67. printf("semctl delete error\n");
68. if(shmctl(shmid,IPC_RMID,NULL)==-1)
69. printf("shmctl delete error\n");
70. }