• io+day8


     

    1. #ifndef __SEM
    2. 2 #define __SEM
    3. 3
    4. 4 //声明一个创>
    5. 5 int init_sem(
    6. 6
    7. 7 //声明一个p操
    8. 8 int P(int sem
    9. 9
    10. 10 //声明一个v操
    11. 11 int W(int sem
    12. 12
    13. 13 //声明一个删>
    14. 14 int del_sem(i
    15. 15
    16. 16 #endif
    1. 1 #include
    2. 2 union semun {
    3. 3 int val; /* Value for SETVAL */
    4. 4 struct semid_ds *buf; /* Buffer for IPC_STAT, IPC_SET */
    5. 5 unsigned short *array; /* Array for GETALL, SETALL */
    6. 6 struct seminfo *__buf; /* Buffer for IPC_INFO
    7. 7 (Linux-specific) */
    8. 8 };
    9. 9 //信号灯集里每个信号灯的初始化
    10. 10 int sem_value(int semid,int semno,int semvalue)
    11. 11 {
    12. 12 union semun us;
    13. 13 us.val=semvalue;
    14. 14 if(semctl(semid,semno,SETVAL,us)==-1)
    15. 15 {
    16. 16 perror("semctr");
    17. 17 return -1;
    18. 18 }
    19. 19 return 0;
    20. 20 }
    21. 21 //创建信号灯集并初始化函数
    22. 22 int init_sem(int semnum)
    23. 23 {
    24. 24 //1.创建一个key钥匙
    25. 25 key_t key;
    26. 26 if((key=ftok("/",'t'))==-1)
    27. 27 {
    28. 28 perror("ftok");
    29. 29 return -1;
    30. 30 }
    31. 31 //2.创建一个信号灯集
    32. 32 int semid;
    33. 33 if((semid=semget(key,semnum,IPC_CREAT|IPC_EXCL|0664))==-1)
    34. 34 {
    35. 35 if(errno==EEXIST)
    36. 36 {
    37. 37 //防止多进程同时调用时多次初始化
    38. 38 semid=semget(key,semnum,IPC_CREAT|0664);
    39. 39 return semid;
    40. 40 }
    41. 41 perror("semget");
    42. 42 return -1;
    43. 43 }
    44. 44 //3.信号灯集初始化
    45. 45 for(int i=0;i
    46. 46 {
    47. 47 if(i==0)
    48. 48 {
    49. 49 //参数1:id
    50. 50 //参数2:初始化的信号灯编号
    51. 51 //参数3:初始化的信号灯的value值
    52. 52 sem_value(semid,i,1);
    53. 53 }
    54. 54 else
    55. 55 {
    56. 56 sem_value(semid,i,0);
    57. 57 }
    58. 58 }
    59. 59 return semid;
    60. 60 }
    61. 61
    62. 62 //p操作函数
    63. 63 int P(int semid,int semno)
    64. 64 {
    65. 65 struct sembuf buf;
    66. 66 buf.sem_num=semno;//灯集里灯编号
    67. 67 buf.sem_op=1; //释放资源
    68. 68 buf.sem_flg=0; //阻塞
    69. 69 if(semop(semid,&buf,1)==-1)
    70. 70 {
    71. 71 perror("semop");
    72. 72 return -1;
    73. 73 }
    74. 74 return 0;
    75. 75
    76. 76 }
    77. 77 //w操作函数
    78. 78 int W(int semid,int semno)
    79. 79 {
    80. 80 struct sembuf buf;
    81. 81 buf.sem_num=semno;//灯集里灯编号
    82. 82 buf.sem_op=-1; //申请资源
    83. 83 buf.sem_flg=0; //阻塞
    84. 84 if(semop(semid,&buf,1)==-1)
    85. 85 {
    86. 86 perror("semop");
    87. 87 return -1;
    88. 88 }
    89. 89 return 0;
    90. 90 }
    91. 91
    92. 92 //删除信号灯的函数
    93. 93 int del_sem(int semid)
    94. 94 {
    95. 95 if(semctl(semid,0,IPC_RMID,0)==-1)
    96. 96 {
    97. 97 perror("semctl");
    98. 98 return -1;
    99. 99 }
    100. 100 return 0;
    101. 101 }
    1. 1 #include
    2. 2 #include "sem.h"
    3. 3 int main(int argc, const char *argv[])
    4. 4 {
    5. 5 //创建钥匙
    6. 6 key_t key=-1;
    7. 7 if((key=ftok("/",'c'))==-1)
    8. 8 {
    9. 9 perror("ftok");
    10. 10 return -1;
    11. 11 }
    12. 12 //创建共享享内存
    13. 13 int shmid;
    14. 14 if((shmid=shmget(key,4096,IPC_CREAT|0664))=
    15. 15 {
    16. 16 perror("shmget");
    17. 17 return -1;
    18. 18 }
    19. 19 //映射到用户空间
    20. 20 char *adder;
    21. 21 if((adder=shmat(shmid,NULL,0))==(void *)-1)
    22. 22 {
    23. 23 perror("shmat");
    24. 24 return -1;
    25. 25 }
    26. 26 //创建一个信号灯集
    27. 27 int semid;
    28. 28 semid=init_sem(4);
    29. 29 //创建父子进程
    30. 30 pid_t pid;
    31. 31 pid=fork();
    32. 32 if(pid<0)
    33. 33 {
    34. 34 perror("fork");
    35. 35 return -1;
    36. 36 }
    37. 37 else if(pid>0)
    38. 38 {
    39. 39 //父进程
    40. 40 while(1)
    41. 41 {
    42. 42 //等待0信号资源
    43. 43 W(semid,0);
    44. 44 fgets(adder,4096,stdin);
    45. 45 adder[strlen(adder)-1]='\0';
    46. 46 //释放1信号资源
    47. 47 P(semid,1);
    48. 48 if(strcmp(adder,"quit")==0)
    49. 49 {
    50. 50 break;
    51. 51 }
    52. 52 }
    53. 53 wait(NULL);
    54. 54 }
    55. 55 else
    56. 56 {
    57. 57 //子进程
    58. 58 while(1)
    59. 59 {
    60. 60 //等待3信号资源
    61. 61 W(semid,3);
    62. 62 //房子里面拿东西
    63. 63 printf("共享内存数据:%s\n",adder);
    64. 64 //释放2信号资源
    65. 65 P(semid,2);
    66. 66 if(strcmp(adder,"quit")==0)
    67. 67 {
    68. 68 break;
    69. 69 }
    70. 70 }
    71. 71 exit(EXIT_SUCCESS);
    72. 72 }
    73. 73 //取消链接
    74. 74 shmdt(adder);
    75. 75 return 0;
    76. 76 }

  • 相关阅读:
    Jenkins 相关内容
    Mysql词法分析实验(一)
    全链路压测的“谜”
    java基于微信小程序的劳务知识分享系统 uniapp 小程序
    小白也能搞通UDP通信(88E1111 RGMII 接口)
    Creo 9.0二维草图的诊断:重叠几何
    软件工程总结
    第13篇 2D绘图(三)绘制文字
    能实现单个电机的启停、正反转和PWM直流调速,电机运行时数码管显示为1,电机停止时数码管显示为0,液晶屏在电机正转时显示字符F,反转时显示R,并显示当前转速。
    杭电多校 7170 Package Delivery
  • 原文地址:https://blog.csdn.net/ZMH12345_/article/details/134431040