您的当前位置:首页正文

同步和互斥实验-吃水果问题、消费者问题之欧阳化创编

2023-06-08 来源:年旅网
欧阳化创编 2021.02.06

实验3 报告

时间:2021.02.06 创作:欧阳化 源程序1 /**

作者:wwj

时间:2012/4/12 功能:实现吃水果问题

**题目内容:桌子有一只盘子,只允许放一个水果,父亲专向盘子放苹果,母亲专向盘子放桔子儿子专等吃盘子的桔子,女儿专等吃盘子的苹果。只要盘子为空,父亲或母亲就可以向盘子放水果,仅当盘子有自己需要的水果时,儿子和女儿可从盘子取出。请给出四个人之间的同步关系,并用pv操作实现四个人的正确活动的问题。**

**题目分析:父亲和女儿是相互制约的,父亲进程执行完即往盘中放入苹果后,女儿进程才能执行即吃苹果,是同步关系;

母亲和儿子是相互制约的,母亲进程执行完即往盘中放入桔子,儿子进程才能执行即吃桔子,也是同步关系

而父亲和母亲这两个进程不能同时进行,是互斥关系;** **/

欧阳化创编 2021.02.06

欧阳化创编 2021.02.06

#include #include using namespace std; //声明句柄

HANDLE EmptyPlate; HANDLE Apple; HANDLE orange; HANDLE fatherThread; HANDLE motherThread; HANDLE sonThread; HANDLE daughterThread; //线程函数声明

DWORD WINAPI father(LPVOID IpParameter); DWORD WINAPI mother(LPVOID IpParameter); DWORD WINAPI daughter(LPVOID IpParameter); DWORD WINAPI son(LPVOID IpParameter); int main() { 盘子

Apple = CreateSemaphore(NULL,0,1,NULL); //苹果

欧阳化创编 2021.02.06

//创建信号量

EmptyPlate = CreateSemaphore(NULL,1,1,NULL); //

欧阳化创编 2021.02.06

orange = CreateSemaphore(NULL,0,1,NULL); //桔子 //创建线程

fatherThread

CreateThread(NULL,0,father,NULL,0,NULL);

motherThread

CreateThread(NULL,0,mother,NULL,0,NULL);

daughterThread

CreateThread(NULL,0,daughter,NULL,0,NULL);

sonThread

CreateThread(NULL,0,son,NULL,0,NULL); //等线程的结束

WaitForSingleObject(fatherThread,INFINITE); WaitForSingleObject(motherThread,INFINITE); WaitForSingleObject(daughterThread,INFINITE); WaitForSingleObject(sonThread,INFINITE); //关闭线程句柄

CloseHandle(fatherThread);

CloseHandle(motherThread); CloseHandle(daughterThread); CloseHandle(sonThread); //关闭信号量句柄

CloseHandle(EmptyPlate);

欧阳化创编 2021.02.06

=

=

=

=

欧阳化创编 2021.02.06

}

CloseHandle(Apple); CloseHandle(orange); return 0;

//父亲线程函数

DWORD WINAPI father(LPVOID IpParameter) {

for(int i = 0; i < 5; ++i){

WaitForSingleObject(EmptyPlate, INFINITE); //

P操作 作

}

//母亲线程函数

DWORD WINAPI mother(LPVOID IpParmeter) {

for(int i = 0; i < 5; ++i){

欧阳化创编 2021.02.06

// 开始临界区

cout << \"\\nFather往盘中放一个水果\\n\"; // 结束临界区

ReleaseSemaphore(Apple, 1, NULL);

// V操

}

return 0;

欧阳化创编 2021.02.06

WaitForSingleObject(EmptyPlate, INFINITE); //

P操作 作 操作

cout<<\"女儿吃苹果\"<ReleaseSemaphore(EmptyPlate,1,NULL);

}

return 0; }

//女儿线程函数

DWORD WINAPI daughter(LPVOID IpParameter) {

while(1) {

WaitForSingleObject(Apple,INFINITE); //p

// 开始临界区

cout << \"\\nMother往盘中放一个桔子\\n\"; // 结束临界区

ReleaseSemaphore(orange, 1, NULL); // V操

//v操作

}

return 0;

欧阳化创编 2021.02.06

欧阳化创编 2021.02.06

操作

}

//儿子线程函数

DWORD WINAPI son(LPVOID IpParameter) {

while(1) {

WaitForSingleObject(orange,INFINITE); //p

cout<<\"儿子吃苹果\"<ReleaseSemaphore(EmptyPlate,1,NULL);

//v操作

}

}

return 0;

程序运行结果截图:

运行结果分析:从运行结果可知父进程执行完后,女儿进程立即执行,这说明父进程跟女儿进程有时序关系,只有当父进程执行之后,女儿进程才会执行,女儿进程是父进程的子线程,他们具有同步关系,同理;母亲进程跟儿子进程,也是同步关系。 源程序2 /**

欧阳化创编 2021.02.06

欧阳化创编 2021.02.06

作者:wwj

时间:2012/4/12

功能:实现生产者和消费者正常活动

题目内容:生产者-消费者问题,是指两组进程共享一个环形的缓冲区。一组进程被称为生产者,另一组进程被称为消费者。

缓冲池是由若干个(程序假设为4个)大小相等的缓冲区组成的,每个缓冲区可以容纳一个产品。生产者进程不断地将生产的产品放入缓冲池,

消费者进程不断地将产品从缓冲池取出。用PV操作实现生产者和消费者的正常活动的程序 题目分析:

在生产者-消费者问题中,既存在进程同步问题,也存

在着临界区的互斥问题。当缓冲区都满时,表示供大于求,

生产者停止生产,进入等待状态,同时唤醒消费者;当缓冲区都空时,表示供不应求,消费者停止消费,唤醒生产者。

这说明了,生产者和消费者存在同步关系。

对于缓冲池,它显然是一个临界资源,所有的生产者

和消费者都要使用它,

而且都要改变它的状态,故对于缓冲池的操作必须是互斥

欧阳化创编 2021.02.06

欧阳化创编 2021.02.06

的。 */

#include #include using namespace std; const int n=4; //声明全局变量 int i=0,j=0;

//i和j分别指向缓冲区

int buffer[n]; //缓冲池

int ItemP=0; //用来存放生产的产品 int ItemC=0; //用来存放消费的产品 //声明句柄 HANDLE mutex; HANDLE empty;

//缓冲池信号量 //空缓冲区信号量

HANDLE full; //满缓冲区信号量

HANDLE pThread; //producer线程句柄 HANDLE cThread; //consumer线程句柄 //声明进程函数

DWORD WINAPI producer(LPVOID IpParameter); DWORD WINAPI consumer(LPVOID IpParameter); int main() {

欧阳化创编 2021.02.06

欧阳化创编 2021.02.06

//创建信号量

mutex = CreateSemaphore(NULL,1,1,NULL); empty = CreateSemaphore(NULL,1,4,NULL); full = CreateSemaphore(NULL,0,4,NULL); cout<<\"市场运作开始。。。。。\"<pThread

CreateThread(NULL,0,producer,NULL,0,NULL);

cThread

CreateThread(NULL,0,consumer,NULL,0,NULL); //等待相应线程结束

WaitForSingleObject(pThread,INFINITE); WaitForSingleObject(cThread,INFINITE); //关闭线程句柄

CloseHandle(pThread); CloseHandle(cThread); //关闭信号量句柄 CloseHandle(mutex); CloseHandle(empty); CloseHandle(full);

cout<<\"整个市场运营结束。。。。\"<return 0;

欧阳化创编 2021.02.06

=

=

欧阳化创编 2021.02.06

}

//producer线程函数的定义

DWORD WINAPI producer(LPVOID IpParameter) {

for(int k=0;k<5;k++) {

cout<<\"\\nproducer

生产一个产品

\"<WaitForSingleObject(empty,INFINITE);

ItemP=ItemP+1;

//增加一个

//P操作

WaitForSingleObject(mutex,INFINITE); cout<<\"\\n把一个产品放入了一个空的缓

冲区\"<i=(i+1)%n;

buffer[i]=ItemP; //将产品放入缓冲

ReleaseSemaphore(mutex,1,NULL);

//V操作

}

欧阳化创编 2021.02.06

ReleaseSemaphore(full,1,NULL);

欧阳化创编 2021.02.06

}

return 0;

DWORD WINAPI consumer(LPVOID IpParameter) {

for(int k=0;k<5;k++) {

WaitForSingleObject(full,INFINITE); //P

WaitForSingleObject(mutex,INFINITE); ItemC=buffer[j];

//将缓冲区里的产

品取出,放入消费产品里头

j=(j+1)%n;

//j指向下一

个满的缓冲区 产品

}

欧阳化创编 2021.02.06

ReleaseSemaphore(mutex,1,NULL);

//V操作

ReleaseSemaphore(empty,1,NULL);

cout<<\"\\n消费者消费一个产品\"<//消费一个

}

return 0;

欧阳化创编 2021.02.06

程序运行截图如下:

运行结果分析:从运行结果来看,整个市场运作有两种状态, 一种状态是生产着连续生产两个产品,每生产一个产品后,立马把产品产品放入缓冲区,接着消费者消费产品;另一种状态是消费者先把缓冲区里面的产品消费,然后生产者把已经生产的产品放入缓冲区里;生产者和消费者即存在同步关系,又存在互斥关系,只是相对而言的,对于缓冲区来说,当缓冲区满的时候,只能由消费者消费产品,接着生产者才能把产品放入缓冲区;当缓冲区为空时,只能由生产者生产产品并把产品放入缓冲区,接着消费者才能消费产品;这两种关系都属于同步关系;对于缓冲池来说,缓冲池只有一个,生产者和消费者只能有一个使用它,并且他们不存在时序关系,到底是谁先使用,只能靠市场的调度和控制。

时间:2021.02.06 创作:欧阳化 欧阳化创编 2021.02.06

因篇幅问题不能全部显示,请点此查看更多更全内容