进程同步与互斥处理

  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。

二、 概要设计
1.方案分析
题目中要求缓冲区是临界资源,写入数据帧时不能进行数据帧的读取,同时, 读取数据帧时也不能进行数据帧的写入, 所以, 数据读取和数据写入是一队互斥的进程。 因此可以定义一个互斥信号量,对其进行 PV 操作以实现两个进程之间互斥。 2 由于题目中定义的缓冲区只能存放十个数据,一次读入只能读取一个数据,一 次写入也只能一个数据,当缓冲区满了就不在写入,缓冲区空就不在读取。为了实现其 中的同步关系,我们定义两个信号量,表示缓冲区的状态,对其分别作 PV 操作。
五、 使用说明及测试结果
1.使用说明:
点击打开应用程序 proj3.exe。程序将会运行,15s 后停止运行,运 行界面如下两幅图:
六、 源程序
#include<iostream> #include<windows.h> using namespace std; typedef int semaphore; int frame_size; const int process_time=3; const int collectstep_time=500; const int TimeLimit=15000; const int Queue_size=10; //定义互斥信号量访问临界资源 HANDLE mutex=CreateMutex(NULL, false, "mutex"); //信号量 full: 缓冲池中等待处理的数据帧数,初值为 0 HANDLE full=CreateSemaphore(NULL, 0, Queue_size, "full"); //信号量 empty: 空余的缓冲区数,初值为 Queue_size 大小 HANDLE empty=CreateSemaphore(NULL, Queue_size, Queue_size, "empty");
//信号量是一种特殊的整型变量
//每 Byte 数据帧处理时间 3ms //数据采集间隔时间 500ms //程序运行时间 15s //队列长度
//定义共享缓冲区 semaphore buffer[Queue_size]; int in=0; int out=0; int buNum=0;
//存储产品编号 //采集产品位置 //处理产品位置 //待处理数据个数
void collectBuffer() { frame_size = rand() % 600; buNum++; in=(in+1)%Queue_size; buffer[in]=frame_size; }
//数据采集 //产生数据帧大小的随机数
//****************Get 进程******************* DWORD WINAPI Get(LPVOID pParm){ while(1){ WaitForSingleObject(empty,INFINITE); //P(empty)生产者信号量-1 WaitForSingleObject(mutex,INFINITE); //P(mutex)获取线程间互斥信号 collectBuffer(); cout<<" 新 数 据 帧 大 小 "<<frame_size<<" Byte,"<<" 待 处 理 数 据 帧 数 目 为 "<<buNum<<endl; ReleaseMutex(mutex); //V(mutex)释放线程间互斥信号 ReleaseSemaphore(full,1,NULL); //V(full)消费者信号量+1 Sleep(collectstep_time); //采集数据间隔 } return 0; } //************Process 进程************ DWORD WINAPI Process(LPVOID pParm){ while(1){ out=(out+1)%Queue_size; WaitForSingleObject(full,INFINITE); //P(full)消费者信号量-1 WaitForSingleObject(mutex,INFINITE); //P(mutex) 获得线程间互斥 信号 cout<<" 正 在 处 理 大 小 "<<buffer[out]<<" Byte,"<<" 处 理 时 间 为 "<<buffer[out]*3<<"ms, 请稍后。 。 。"<<endl; buNum--; ReleaseMutex(mutex); //V(mutex)释放线程间互斥信号 ReleaseSemaphore(empty,1,NULL); //V(empty)生产者信号量+1 Sleep(buffer[out]*3); //处理数据
一.实验要求:
1) 缓冲区是临界资源,写入数据帧时不能进行数据帧的读取, 同时,读取数据帧时也不能进行数据帧的写入,读取/写入数据 帧的时间延时可忽略不计; 2) 数据采集进程每次从前置机获取的数据帧大小随机产生, 但不大于600Byte,两次数据采集的时间间隔为500ms(注意:在 此时间间隔内不占用缓冲区) ; 3) 数据处理进程只在读取数据帧的时候占用临界资源,数据 处理过程中并不占用缓冲区,数据帧的处理时间跟其大小成正 比,每Byte 的处理时间为3ms。
} return 0; } //************主进程************ int main(){ //创建进程 HANDLE hThread1=CreateThread(NULL, 0, Get,NULL,0,NULL); HANDLE hThread2=CreateThread(NULL,0, Process,NULL,0,NULL); //控制程序运行时间 Sleep(TimeLimit); //消除进程 CloseHandle(hThread1); CloseHandle(hThread2); cout<<endl<<"……Time is up. Exit……"<<endl; return 0; }
一次写入也只能一个数据,当缓冲区满了就不在写入,缓冲区空就不在读取。为了实现 其中的同步关系,我们定义两个信号量,表示缓冲区的状态,对其分别作 PV 操作。
3.信号量设计:
full: 缓冲池中等待处理的数据帧数,初值为 0; empty:空余的缓冲区数,初值为 Queue_size 大小 mutex:互斥信号量,对临界区(缓冲区)互斥访问
1
2.主要功能模块的功能
写入数据_Get 进程 读取数据和处理数据_Process 进程
3.主程序的流程及各程序模块之间的层次关系
创建 Get 进程、Process 进程 控制程序运行时间 消除进程
三.详细设计
1.相关进程功能
写入数据_Get 进程 读取数据和处理数据_Process 进程
4.PV 操作的使用
//****************Get 进程******************* DWORD WINAPI Get(LPVOID pParm){ while(1){ WaitForSingleObject(empty,INFINITE); /P(empty)生产者信号量-1 WaitForSingleObject(mutex,INFINITE); //P(mutex)获取线程间互斥信号 collectBuffer(); cout<<" 新 数 据 帧 大 小 "<<frame_size<<" Byte,"<<" 待 处 理 数 据 帧 数 目 为 "<<buNum<<endl; ReleaseMutex(mutex); //V(mutex)释放线程间互斥信号 ReleaseSemaphore(full,1,NULL); //V(full)消费者信号量+1 Sleep(collectstep_time); //采集数据间隔 } return 0; } //************Process 进程************ DWORD WINAPI Process(LPVOID pParm){ while(1){ out=(out+1)%Queue_size; WaitForSingleObject(full,INFINITE); WaitForSingleObject(mutex,INFINITE); cout<<" 正 在 处 理 大 小 "<<buffer[out]<<" "<<buffer[out]*3<<"ms, 请稍后。 。 。"<<endl; buNum--; ReleaseMutex(mutex); ReleaseSemaphore(empty,1,NULL); Sleep(buffer[out]*3); } return 0; }
2.进程间同步/互斥关系
1
题目中要求缓冲区是临界资源, 写入数据帧时不能进行数据帧的读取, 同时,
读取数据帧时也不能进行数据帧的写入, 所以, 数据读取和数据写入是一队互斥的进程。 因此可以定义一个互斥信号量,对其进行 PV 操作以实现两个进程之间互斥。
2
由于题目中定义的缓冲区只能存放十个数据,一次读入只能读取一个数据,
实验题目:进程同步与互斥处理
数据采集进程 获取前置机传来的数据帧并存放在等待缓冲池
中,如图1 所示。等待缓冲池由10 个缓冲区组成环形队列,每 个缓冲区只允许存放1 个待处理的数据帧, 当缓冲池满时不允许 继续存放数据帧。
数据处理进程只有在缓冲池有待处理的数据帧时才不断读取缓Leabharlann Baidu
冲区中的数据帧,并进行处理。
//P(full)消费者信号量-1 //P(mutex)获得线程间互斥信号 Byte,"<<" 处 理 时 间 为
//V(mutex)释放线程间互斥信号 //V(empty)生产者信号量+1 //处理数据
四.分析
1.根据执行过程(程序输出结果) ,分析存在的问题。 有输出结果可以看出, 由于缓冲区大小有限, 当数据过大, 处理时间过长是, 缓冲区会出现拥挤的状态,即无法读入数据,是写入数据的进程被挂起。 为了解决这一问题,可以考虑增大缓冲区的容量,但是实践可知,只要时间 不断走下去,不管缓冲区多大,到一定时间后总会变满。分析可知,只要减小数 据的大小,或者减小处理数据的时间,就可以解决这一问题。
相关文档
最新文档