10.20作业

博客围绕使用信号灯实现三个进程分别输出abcabcabc展开,涉及sem.h、zysem.h头文件以及a.c、b.c、c.c源文件。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

题目:使用信号灯实现三个进程分别实现abcabcabc

sem.h

  1. #ifndef __SEM_H__
  2. #define __SEM_H__
  3. int init_sem(); //创建并初始化一个信号灯集
  4. int P(int semid,int semnum); //申请senid信号灯集中的semnum号灯的资源
  5. int V(int semid,int semnum); //释放semid信号灯集中的semnum号灯的资源
  6. int sem_del(int semid); //删除信号灯集
  7. #endif

zysem.h 

  1. #include <head.h>
  2. union semun
  3. {
  4. int val;
  5. struct semid_ds*buf;
  6. unsigned short *array;
  7. struct seminfo *__buf;
  8. };
  9. int init_semnum_value(int semid,int semnum,int value)
  10. {
  11. //为semctl准备第四个参数,是给信号灯设置值
  12. union semun s;
  13. s.val=value;
  14. if(semctl(semid,semnum,SETVAL,s)==-1)
  15. {
  16. perror("semctl error");
  17. return -1;
  18. }
  19. return 0;
  20. }
  21. int init_sem() //创建并初始化一个信号灯集
  22. {
  23. //创建key值
  24. key_t key;
  25. if((key=ftok("./",'k'))==-1)
  26. {
  27. perror("ftok error");
  28. return -1;
  29. }
  30. //2创建信号灯集
  31. int semid;
  32. if((semid=semget(key,3,IPC_CREAT| IPC_EXCL | 0664))==-1)
  33. {
  34. //对错误码进行判断,如果错误码等于EEXIST
  35. if(errno==EEXIST)
  36. {
  37. semid=semget(key,3,IPC_CREAT|0664);
  38. }
  39. else
  40. {
  41. perror("semget error");
  42. return -1;
  43. }
  44. }
  45. else
  46. {
  47. //3初始化信号灯
  48. //调用自定义函数,为每个灯初始化
  49. //参数1,要处理的信号灯集id
  50. //参数2:要处理的信号灯编号
  51. //参数3:给对应编号的灯初始值/当为1时不会堵塞
  52. init_semnum_value(semid,0,1);
  53. init_semnum_value(semid,1,0);
  54. init_semnum_value(semid,2,0);
  55. }
  56. return semid; //将创建好的信号灯集id返回
  57. }
  58. //申请senid信号灯集中的semnum号灯的资源
  59. int P(int semid,int semnum)
  60. {
  61. //定义设置灯信息的结构体的变量
  62. struct sembuf buf;
  63. buf.sem_num=semnum; //要处理的信号灯编号
  64. buf.sem_op=-1; //表示申请资源
  65. buf.sem_flg=0; //阻塞方式申请资源
  66. //将semnum号灯的资源减1操作
  67. if(semop(semid,&buf,1)==-1)
  68. {
  69. perror("p error");
  70. return -1;
  71. }
  72. return 0;
  73. }
  74. int V(int semid,int semnum) //释放semid信号灯集中的semnum号灯的资源
  75. {
  76. //定义设置灯信息的结构体的变量
  77. struct sembuf buf;
  78. buf.sem_num=semnum; //要处理的信号灯编号
  79. buf.sem_op=1; //表示申请资源
  80. buf.sem_flg=0; //阻塞方式申请资源
  81. //将semnum号灯的资源减1操作
  82. if(semop(semid,&buf,1)==-1)
  83. {
  84. perror("v error");
  85. return -1;
  86. }
  87. return 0;
  88. }
  89. int sem_del(int semid) //删除信号灯集
  90. {
  91. if(semctl(semid,0,IPC_RMID,0)==-1)
  92. {
  93. perror("semctl error");
  94. return -1;
  95. }
  96. return 0;
  97. }

a.c

  1. #include <head.h>
  2. #include "sem.h" //封装了信号灯集的函数头文件
  3. #define SIZE 4096
  4. int main(int argc, const char *argv[])
  5. {
  6. //一创建信号灯集并初始化
  7. int semid;
  8. if((semid=init_sem())==-1)
  9. {
  10. printf("创建信号灯集失败\n");
  11. return -1;
  12. }
  13. //1获取key值
  14. key_t key;
  15. if((key=ftok("./",'s'))==-1)
  16. {
  17. perror("ftok error");
  18. return -1;
  19. }
  20. //2创建共享内存
  21. int shmid;
  22. if((shmid=shmget(key,SIZE,IPC_CREAT|0664))==-1)
  23. {
  24. perror("shmget error");
  25. return -1;
  26. }
  27. //3映射内存地址
  28. char *addr=shmat(shmid,NULL,0);
  29. if(addr==(void*)-1)
  30. {
  31. perror("shmat error");
  32. return -1;
  33. }
  34. printf("addr=%p\n",addr);//输出共享内存的地址
  35. //循环输入
  36. for(int i=1;i<5;i++)
  37. {//申请一号灯的资源
  38. P(semid,2);
  39. //向共享内存中写数据
  40. printf("请输入>>");
  41. *(char*)addr='a';//直接从终端获取数据到共享内存中
  42. printf("%c\n",*((char*)addr));
  43. addr[strlen(addr)-1]=0;
  44. sleep(1);
  45. //释放0号等资源(就是释放信号,0可以运行了)
  46. V(semid,0);
  47. if(strcmp(addr,"quit")==0)
  48. {
  49. break;
  50. }
  51. }
  52. //4取消映射
  53. if(shmdt(addr)==-1)
  54. {
  55. perror("shmdt error");
  56. return -1;
  57. }
  58. //删除共享内存
  59. //shmctl(shmid,IPC_RMID,NULL);
  60. //四 删除信号灯集
  61. //sem_del(semid);
  62. return 0;
  63. }

b.c

  1. #include <head.h>
  2. #include "sem.h" //封装了信号灯集的函数头文件
  3. #define SIZE 4096
  4. int main(int argc, const char *argv[])
  5. {
  6. //一创建信号灯集并初始化
  7. int semid;
  8. if((semid=init_sem())==-1)
  9. {
  10. printf("创建信号灯集失败\n");
  11. return -1;
  12. }
  13. //1获取key值
  14. key_t key;
  15. if((key=ftok("./",'k'))==-1)
  16. {
  17. perror("ftok error");
  18. return -1;
  19. }
  20. //2创建共享内存
  21. int shmid;
  22. if((shmid=shmget(key,SIZE,IPC_CREAT|0664))==-1)
  23. {
  24. perror("shmget error");
  25. return -1;
  26. }
  27. //3映射内存地址
  28. char *addr=shmat(shmid,NULL,0);
  29. if(addr==(void*)-1)
  30. {
  31. perror("shmat error");
  32. return -1;
  33. }
  34. printf("addr=%p\n",addr);//输出共享内存的地址
  35. //循环输入
  36. for(int i=1;i<5;i++)
  37. {//申请一号灯的资源
  38. P(semid,0);
  39. //向共享内存中写数据
  40. printf("请输入>>");
  41. *(char*)addr='b';//直接从终端获取数据到共享内存中
  42. printf("%c\n",*((char*)addr));
  43. addr[strlen(addr)-1]=0;
  44. sleep(1);
  45. //释放0号等资源(就是释放信号,0可以运行了)
  46. V(semid,1);
  47. if(strcmp(addr,"quit")==0)
  48. {
  49. break;
  50. }
  51. }
  52. //4取消映射
  53. if(shmdt(addr)==-1)
  54. {
  55. perror("shmdt error");
  56. return -1;
  57. }
  58. //删除共享内存
  59. //shmctl(shmid,IPC_RMID,NULL);
  60. //四 删除信号灯集
  61. //sem_del(semid);
  62. return 0;
  63. }

c.c

  1. #include <head.h>
  2. #include "sem.h" //封装了信号灯集的函数头文件
  3. #define SIZE 4096
  4. int main(int argc, const char *argv[])
  5. {
  6. //一创建信号灯集并初始化
  7. int semid;
  8. if((semid=init_sem())==-1)
  9. {
  10. printf("创建信号灯集失败\n");
  11. return -1;
  12. }
  13. //1获取key值
  14. key_t key;
  15. if((key=ftok("./",'k'))==-1)
  16. {
  17. perror("ftok error");
  18. return -1;
  19. }
  20. //2创建共享内存
  21. int shmid;
  22. if((shmid=shmget(key,SIZE,IPC_CREAT|0664))==-1)
  23. {
  24. perror("shmget error");
  25. return -1;
  26. }
  27. //3映射内存地址
  28. char *addr=shmat(shmid,NULL,0);
  29. if(addr==(void*)-1)
  30. {
  31. perror("shmat error");
  32. return -1;
  33. }
  34. printf("addr=%p\n",addr);//输出共享内存的地址
  35. //循环输入
  36. for(int i=1;i<5;i++)
  37. {//申请一号灯的资源
  38. P(semid,1);
  39. //向共享内存中写数据
  40. printf("请输入>>");
  41. *(char*)addr='c';//直接从终端获取数据到共享内存中
  42. printf("%c\n",*((char*)addr));
  43. addr[strlen(addr)-1]=0;
  44. sleep(1);
  45. //释放0号等资源(就是释放信号,0可以运行了)
  46. V(semid,2);
  47. if(strcmp(addr,"quit")==0)
  48. {
  49. break;
  50. }
  51. }
  52. //4取消映射
  53. if(shmdt(addr)==-1)
  54. {
  55. perror("shmdt error");
  56. return -1;
  57. }
  58. //删除共享内存
  59. //shmctl(shmid,IPC_RMID,NULL);
  60. //四 删除信号灯集
  61. //sem_del(semid);
  62. return 0;
  63. }

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值

举报

选择你想要举报的内容(必选)
  • 内容涉黄
  • 政治相关
  • 内容抄袭
  • 涉嫌广告
  • 内容侵权
  • 侮辱谩骂
  • 样式问题
  • 其他
程序员都在用的中文IT技术交流社区

程序员都在用的中文IT技术交流社区

专业的中文 IT 技术社区,与千万技术人共成长

专业的中文 IT 技术社区,与千万技术人共成长

关注【CSDN】视频号,行业资讯、技术分享精彩不断,直播好礼送不停!

关注【CSDN】视频号,行业资讯、技术分享精彩不断,直播好礼送不停!

客服 返回顶部