第三季-第17课-信号量同步编程

第17课-信号量同步编程

 

17.1 核心概念--进程同步

一组并发进程进行互相合作、互相等待,使得各进程按一定的顺序执行的过程称为进程间的同步。

17.2 生产者消费者问题

1. 问题描述

这里面有两个角色:生产者和消费者。假设生产者生产的产品需要两步才能完成并且使用。但是,当生产者刚刚完成了对产品的第一步加工的时候,产品就被消费者买走了。可是他们之间并没有相应的沟通,这就导致,消费者会以为他买到了完成的产品。

2. 程序化

在文件夹里面创建producer.c和customer.c文件,同时创建文件夹ship。

producer.c

#include<sys/types.h>

#include<sys/stat.h>

#include<fcntl.h>

#include<unistd.h>

void main()

{

         int fd;

         //1.创建产品--文件

         fd = open("./product.txt",O_RDWR|O_CREAT,0775);

         //2.休息

         sleep(20);

         //3.向产品文件中填充内容

         write(fd,"the product is finished!",25);

         //4.关闭文件

         close(fd);

}

customer.c

#include<stdlib.h>

void main()

{

         //取走产品文件

         system("cp ./product.txt ./ship");

}

运行结果:在两个一样的终端中分别运行./producer和./customer文件,我们会在文件夹/ship中,找到空白的文件product.txt。

3. 加入同步控制量

我们设置信号量的初始值是0,只有当生产者完成程序运行的时候才是1,这样就能解决问题。

./producer.c

#include<sys/types.h>

#include<sys/stat.h>

#include<fcntl.h>

#include<unistd.h>

#include<sys/ipc.h>

#include<sys/sem.h>

void main()

{

         int fd;

         key_t key;

         int semid;

         struct sembuf sops;

         //键值的设置

         key = ftok("/root",2);

         //创建信号量

         semid = semget(key,1,IPC_CREAT);

         //设置初始值为0

         semctl(semid,0,SETVAL,0);

         //创建产品--文件

         fd = open("./product.txt",O_RDWR|O_CREAT,0775);

         //休息

         sleep(20);

         //向产品文件中填充内容

         write(fd,"the product is finished!",25);

         //关闭文件

         close(fd);

         //释放信号量

         sops.sem_num = 0 ;

         sops.sem_op = 1;

         sops.sem_flg = SEM_UNDO;

         semop(semid,&sops,1);

}

./customer

#include<stdlib.h>

#include<sys/ipc.h>

#include<sys/sem.h>

#include<sys/types.h>

void main()

{

         key_t key;

         int semid;

         struct sembuf sops;

         int ret;

         //键值的设置

         key = ftok("/root",2);

         semid = semget(key,1,IPC_CREAT);

         //获取信号量

         sops.sem_num = 0 ;

         sops.sem_op = -1;

         sops.sem_flg = SEM_UNDO;           /*缺少这一项,可能成功,也可能失败,这里要是不设置它,会失败*/

         //SEM_UNDO表示当程序,用这个信号量出错的时候,系统帮你释放掉这个信号量。

         ret = semop(semid,&sops,1);

         printf("ret is %d! ",ret);   /*显示0表示成功,显示-1表示失败*/

         //取走产品文件

         system("cp ./product.txt ./ship");

}

运行结果:在两个一样的终端中分别运行./producer和./customer文件,我们会看到./customer程序的等待,我们还在/ship文件夹中找到文件product.txt,它里面的内容是:the product is finished!

原文地址:https://www.cnblogs.com/free-1122/p/11351543.html