信号量的互斥与同步

一、信号量互斥
公示栏问题:同学A在公示栏上写“数学课取消”,同学B然后又写了“英语课考试”。但是当,同学A写下“数学课”后。出去了一下,这是同学B写了“英语课考试”,同学A再回来写“取消”。这时我们所要传达的意思就完全不一样了。所以需要引入互斥。

1. 信号量
信号量(又名:信号灯)与其他进 程间通信方式不大相同,主要用 途是保护临界资源(进程互斥) 进程可以根据它判定是否能够访
问某些共享资源。除了用于访问 控制外,还可用于 进程同步

2.信号量分类:
二值信号灯:信号灯的值只能取0或1
计数信号灯:信号灯的值可以取任意非负值。

3.指定键值
①任意指定一个数
缺点:这个数已经被别的IPC对象(消息队列,共享内存)
所使用了,在与新创建的信号量关联时就会失败。

②构造一个尽量不会被别的IPC对象用到的数
方法:使用key_t ftok( char * fname, int id )
Ftok工作原理:将fname和id相组合,组成一个信号量

4.程序代码
student1.c
  1. #include <sys/types.h>
  2. #include <sys/stat.h>
  3. #include <fcntl.h>
  4. #include <unistd.h>
  5. #include <sys/ipc.h>
  6. #include <sys/sem.h>

  7. void main()
  8. {
  9.     int fd;
  10.     int ret;
  11.     key_t key;
  12.     int semid;
  13.     struct sembuf sops;
  14.     
  15.     /*创建键值*/
  16.     key = ftok("/home", 1);

  17.     /*创建并打开信号量集合*/
  18.     semid = semget(key,1,IPC_CREAT);
  19.     ret = semctl(semid, 0, SETVAL, 1);       //将信号量个数初始设置为1

  20.     /*0.打开文件*/
  21.     fd = open("./board.txt",O_RDWR|O_APPEND);
  22.     if(fd < 0)
  23.     {
  24.         printf("file open fialed.\n");
  25.         return;
  26.     }
  27.     /*获取信号量*/
  28.     sops.sem_num = 0;
  29.     sops.sem_op = -1;
  30.     ret = semop(semid, &sops,1);
  31.     

  32.     /*1.向文件公告板写入“数学课”*/
  33.     write(fd, "class math ", 11);
  34.     /*2.暂停休息*/
  35.     sleep(10);
  36.     /*3.向公告板写入“取消”*/
  37.     write(fd, "is cancel ",11);

  38.     /*释放信号量*/
  39.     sops.sem_num = 0;
  40.     sops.sem_op = 1;
  41.     ret = semop(semid, &sops, 1);

  42.     close(fd);
  43. }
student2.c
  1. #include <sys/types.h>
  2. #include <sys/stat.h>
  3. #include <unistd.h>
  4. #include <fcntl.h>
  5. #include <sys/ipc.h>
  6. #include <sys/sem.h>

  7. void main()
  8. {
  9.     int fd;
  10.     int ret;
  11.     key_t key;
  12.     int semid;
  13.     struct sembuf sops;
  14.     /*打开信号量*/
  15.     key = ftok("/home",1);
  16.     semid = semget(key, 1, IPC_CREAT);

  17.     /*打开文件*/
  18.     fd = open("./board.txt", O_RDWR|O_APPEND);

  19.     ret = semctl(semid, 0, GETVAL);
  20.     printf("the value of sem is %d\n",ret);
  21.     
  22.     /*获取信号量*/
  23.     sops.sem_num = 0;
  24.     sops.sem_op = -1;
  25.     semop(semid, &sops, 1);

  26.     /*写入“英语课考试”*/
  27.     write(fd, "english exam", 20);

  28.     /*释放信号量*/
  29.     sops.sem_num = 0;
  30.     sops.sem_op = 1;
  31.     semop(semid, &sops, 1);

  32.     /*结束*/
  33.     close(fd);
  34. }
二、信号量同步
1.进程同步
一组并发进程进行互相合作、互相等待, 使得各进程按一定的顺序执行的过程称为 进程间的同步。

2.生产者消费者问题
生产者生产完产品后,消费者才能把产品拿走。如果还没生产完,消费者就拿走的话,会造成不同步。

3.程序代码
通过生产者设置信号量为0后,只有生产完产品才释放信号量。之后消费者才能取走产品。
productor.c
  1. #include <sys/types.h>
  2. #include <sys/stat.h>
  3. #include <fcntl.h>
  4. #include <unistd.h>
  5. #include <sys/ipc.h>
  6. #include <sys/sem.h>

  7. void main()
  8. {
  9.     int fd;
  10.     key_t key;
  11.     struct sembuf sops;
  12.     int semid;
  13.     /*创建信号量*/
  14.     key = ftok("/root", 1);
  15.     semid = semget(key, 1, IPC_CREAT);
  16.     semctl(semid, 0, SETVAL, 0);

  17.     /*创建文件*/
  18.     fd = open("./product.txt", O_RDWR|O_CREAT, 0666);

  19.     /*休息*/
  20.     sleep(20);

  21.     /*往文件写入内容*/
  22.     write(fd, "write something.", 16);

  23.     /*释放信号量*/
  24.     sops.sem_num = 0;
  25.     sops.sem_op = 1;
  26.     semop(semid, &sops, 1);

  27.     close(fd);
  28. }
customer.c
  1. #include <sys/types.h>
  2. #include <stdlib.h>
  3. #include <sys/ipc.h>
  4. #include <sys/sem.h>

  5. void main()
  6. {
  7.     key_t key;
  8.     int semid;
  9.     struct sembuf sops;
  10.     int ret;
  11.     /*获取信号量*/
  12.     key = ftok("/root", 1);
  13.     semid = semget(key, 1, IPC_CREAT);

  14.     sops.sem_num = 0;
  15.     sops.sem_op = -1;
  16.     sops.sem_flg = SEM_UNDO;
  17.     ret = semop(semid, &sops, 1);
  18.     printf("ret is %d",ret);

  19.     /*取走文件*/
  20.     system("cp ./product.txt ./ship/");

  21. // sops.sem_num = 0;
  22. // sops.sem_op = 1;
  23. // semop(semid, &sops, 1);
  24. }


<script>window._bd_share_config={"common":{"bdSnsKey":{},"bdText":"","bdMini":"2","bdMiniList":false,"bdPic":"","bdStyle":"0","bdSize":"16"},"share":{}};with(document)0[(getElementsByTagName('head')[0]||body).appendChild(createElement('script')).src='http://bdimg.share.baidu.com/static/api/js/share.js?v=89860593.js?cdnversion='+~(-new Date()/36e5)];</script>
阅读(38) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~
评论热议
  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

习惯就好zz

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值