Chinaunix首页 | 论坛 | 博客
  • 博客访问: 273109
  • 博文数量: 223
  • 博客积分: 0
  • 博客等级: 民兵
  • 技术积分: 2145
  • 用 户 组: 普通用户
  • 注册时间: 2014-03-01 10:23
个人简介

该坚持的时候坚持,该妥协的时候妥协,该放弃的时候放弃

文章分类

全部博文(223)

文章存档

2017年(56)

2016年(118)

2015年(3)

2014年(46)

我的朋友

分类: C/C++

2016-10-19 21:04:40

一、信号量互斥
公示栏问题:同学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. }


阅读(304) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~