




已阅读5页,还剩5页未读, 继续免费阅读
版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领
文档简介
设计3 假脱机打印程序与虚拟设备3.1 设计目的理解虚拟设备的工作原理,理解守护程序的概念。图3-1表示假脱机打印程序的工作原理。文件打印请求打印请求客户端程 序图3-1 假脱机程序工作原理服务器端打印请求队列服务器端打印请求接收程序服务器端打印程序服务器端打印机打印请求在网络环境下,连在网络服务器上的打印机要为多个终端服务,每个终端上的用户都可以通过客户端程序向服务器发送打印请求,服务器端的打印请求接收程序接收来自客户端的打印请求,并将该请求存放到磁盘上的打印请求队列中,由服务器端的假脱机打印程序在CPU空闲时从打印请求队列中取出请求信息,并将文件输出到打印机中。这种工作方式不是将文件直接输出到打印机,而是先将待打印的文件缓存到磁盘上,然后立即返回用户程序,从而缩短了用户响应时间,为用户提供了虚拟的快速打印机。这里的磁盘缓存空间就是虚拟设备。服务器端的打印请求接收程序和打印程序都是守护程序,即从开机后就一直运行的程序。3.2 设计要求利用多线程技术编写假脱机打印程序,并设计测试数据以验证程序的正确性。1、界面要求:程序采用简单的控制台界面,运行后在屏幕上显示功能菜单,列出该程序具有的功能,供用户选择。2、功能要求:(1)发送打印请求;(2)查看假脱机打印队列;(3)打印文件;(4)退出。用户选择功能后应该转到相应的处理程序,并在需要时显示程序的执行结果。若用户选择(1)则提示用户输入待打印的文件名称,程序接收输入后将打印请求传送到打印队列中,并回到主菜单;若用户选择(2)则在屏幕上列出打印队列情况,提示按任意键回到主界面;若用户选择(3)则打印队首的文件,显示所打印的文件名称,按任意键回到主界面;若用户选择(4)则退出程序的执行。3.3 数据结构分析字段名称作用file_name文件名称file_size文件大小(以KB为单位)图3-2 FILE_INFO结构体的成员及其作用需要两个数据结构,一个FILE_INFO用来描述打印请求,包括文件名称和文件大小,如图3-2所示。另一个数据结构SPOOL用来描述打印请求队列,如图3-3所示。图3-4描述了程序运行时刻结构体SPOOL的内容。字段名称作用spool_count记录打印队列中的文件个数spool_in记录下一个打印请求存放的位置spool_out记录下一个被打印文件的位置spool_queue打印请求队列(用数组实现)图3-3 SPOOL结构体的成员及其作用spool_count3spool_in3spool_out0spool_queue0sever4KBspool_queue1client3KBspool_queue2myfile7KBspool_queue3spool_queue4图3-4 SPOOL结构体快照3.4 程序结构1、线程划分为了模拟假脱机打印程序,需要三个线程,主线程用于显示主菜单,接收用户的功能选择,显示打印队列情况;打印请求接收/发送线程接收用户的打印请求,并将打印请求存放到打印请求队列;打印线程用来从打印队列中取文件并将其输出到屏幕。2、线程互斥要求三个线程都需要通过控制台终端与用户交互,因此对终端的使用要互斥,以免屏幕混乱(用互斥体h_screen_mutex实现);三个线程都要访问打印请求队列,因此对它要进行互斥操作(用互斥体h_spool_mutex实现);3、同步要求主线程与打印请求接收/发送线程要同步,当用户选择功能(1)时,主线程要通知打印请求接收/发送线程开始接收用户请求(用初始值为0的信号量h_print实现),然后主线程要等待打印请求接收/发送线程发来接收完毕的信号(用初始值为0的信号量h_sendthread_to_mainthread实现);主线程要与打印线程同步,当用户选择功能(3)时,主线程要通知打印线程开始打印文件(用初始值为0的信号量h_semaphore_spool实现),然后主线程要等待打印线程发来打印完毕的信号(用初始值为0的信号量h_spoolthread_to_mainthread实现);(注意:在实际的系统中,打印线程不会等待用户从控制台发命令才开始打印,而是只要有打印请求且CPU空闲就循环不停地打印文件,直至打印队列为空,这时打印线程睡眠。本设计这样做是为了避免打印队列迅速变空。)请求接收/发送线程和打印线程要同步,当打印队列为空时打印线程阻塞,直到请求接收/发送线程将新的请求放入队列;当打印队列满时,请求接收/发送线程阻塞,直到打印线程打印完一个文件空出新位置才能将其唤醒。这两个线程的同步遵循生产者/消费者模型,同步信号量为h_spool_empty和h_spool_full,前者跟踪空位置,后者跟踪打印请求。4、函数设计为了简化程序设计,我们只考虑单机环境,而且将打印请求队列存放在内存中,而不是存放在磁盘中,另外用屏幕输出模拟实际的打印机输出。该程序包括三个线程:主线程模拟客户端程序,sendthread线程模拟打印请求接收程序,spool_thread线程模拟打印程序。该程序使用以下全局变量:spool_buffer是打印请求队列,互斥体h_spool_mutex用来实现对spool_buffer的互斥访问,互斥体h_screen_mutex用来实现对终端的互斥访问,h_send和h_spool_thread分别是打印请求接收/发送线程和打印线程的句柄,h_semaphore_spool和h_spoolthread_to_mainthread是主线程和打印线程之间的同步信号量,h_print和h_sendthread_to_mainthread是主线程和打印请求接收/发送线程之间的同步信号量,h_spool_full和h_spool_empty是打印线程和打印请求接收/发送线程之间的同步信号量。该程序共有五个函数,它们的名称及作用如图3-5所示。函数名称作用sendthread接收用户的打印请求并将其发送到打印请求队列中spool_thread从打印请求队列中取待打印文件并将其输出到屏幕上print_space显示若干个空格list_spool_queue列出打印队列main创建线程,初始化信号量,显示主菜单,根据用户选择执行相应功能图3-5 假脱机打印程序包括的函数及其作用下面给出每个函数的算法描述。(1)list_spool_queue函数申请打印队列互斥使用权P(h_spool_mutex);申请屏幕互斥使用权P(h_screen_mutex);清屏;显示打印队列中当前请求个数;显示表头;对请求队列中的每一个请求在屏幕上输出待打印文件名称以及大小;释放打印队列互斥使用权V(h_spool_mutex);释放屏幕互斥使用权V(h_screen_mutex);(2)sendthread函数 while(1) 等待主线程发送唤醒信号直到用户选择“发送打印请求功能”P(h_print); 申请屏幕互斥使用权P(h_screen_mutex);清屏; 提示并接收用户输入文件名称; 释放屏幕互斥使用权V(h_screen_mutex); 产生随机数作为文件大小; 申请打印队列中的空闲位置P(h_spool_empty);申请打印队列互斥使用权P(h_spool_mutex);将请求放入打印队列当前位置;调整位置指针至下一位置;释放打印队列互斥使用权V(h_spool_mutex);通知打印线程多了一个打印请求V(h_spool_full);唤醒主线程继续画主菜单V(h_sendthread_to_mainthread);(3)spool_thread函数 while(1) 等待主线程发送唤醒信号直到用户选择“打印文件功能”P(h_semaphore_spool); 等待直到sendthread线程发来打印请求P(h_spool_full); 申请打印队列互斥使用权P(h_spool_mutex); 申请屏幕互斥使用权P(h_screen_mutex); 将打印队列中的文件数减1; 在屏幕上输出正在打印的文件名称; 回收该位置(置文件名称为空白,文件大小为0); 下调打印指针;释放屏幕互斥使用权V(h_screen_mutex);释放打印队列互斥使用权V(h_spool_mutex);通知sendthread线程多了一个空位置V(h_spool_empty);唤醒主线程继续画主菜单V(h_spoolthread_to_mainthread); (4)main函数创建两个互斥体;创建六个同步信号量;创建两个线程;while(1)申请屏幕互斥使用权P(h_screen_mutex);显示主菜单;接收用户功能选择;清屏;释放屏幕互斥使用权V(h_screen_mutex);根据功能选择进行分支选择了功能1:唤醒发送线程允许其发送请求到打印队列V(h_print);等待发送线程发送完打印请求P(h_sendthread_to_mainthread);跳出循环;选择了功能2:显示打印队列;跳出循环;选择了功能3:唤醒打印线程允许其打印文件V(h_semaphore_spool);等待打印线程打印完文件P(h_spoolthread_to_mainthread);跳出循环;选择了功能4:返回;3.5 测试程序程序运行的主界面如图3-6所示,输入1后,提示你键入文件名称,你键入文件名称后,程序提示你按任意键回到主菜单,如图3-7所示,回到主菜单后,再选择1两次,分别输入文件名称为file2.ext和file3.cpp,然后回到主菜单,选择2,显示打印请求队列如图3-8所示。按任意键后回到主菜单,选择3打印一个文件,如图3-9所示。按任意键后回到主菜单,选择2打印请求队列,如图3-10所示,可见请求队列中已经少了一个待打印文件了。按任意键后回到主菜单,选择4,结束程序的执行。图3-6 主菜单图3-7 发送请求界面图3-8打印请求队列图3-9 打印文件界面图3-10 打印一个文件后的请求队列3.6参考源代码3.6.1 windows下的参考源程序#include #include #include #include #include #define MAX_SPOOL 5 / 打印请求队列大小,最多能存放五个请求#define DELAY rand()%100 / 用随机数产生文件大小,以KB为单位typedef structchar file_name200;int file_size;FILE_INFO;typedef structint spool_count;int spool_in;int spool_out;FILE_INFO spool_queueMAX_SPOOL;SPOOL;SPOOL spool_buffer;HANDLE h_spool_mutex;HANDLE h_screen_mutex;HANDLE h_send; / 发送线程的句柄HANDLE h_semaphore_spool;HANDLE h_spoolthread_to_mainthread;HANDLE h_sendthread_to_mainthread;HANDLE h_spool_thread; / 打印线程的句柄HANDLE h_spool_full;HANDLE h_spool_empty;HANDLE h_print; DWORD WINAPI sendthread(LPVOID lpParameter) / 打印请求接收/发送线程的线程函数FILE_INFO file_info;while(1)WaitForSingleObject(h_print,INFINITE);WaitForSingleObject(h_screen_mutex,INFINITE);system(cls);printf(enter file name:);scanf(%s,file_info.file_name);ReleaseMutex(h_screen_mutex);srand( (unsigned)time( NULL ) );file_info.file_size=DELAY;WaitForSingleObject(h_spool_empty,INFINITE); WaitForSingleObject(h_spool_mutex,INFINITE);spool_buffer.spool_count+;spool_buffer.spool_queuespool_buffer.spool_in=file_info;spool_buffer.spool_in=(spool_buffer.spool_in+1)%MAX_SPOOL;ReleaseMutex(h_spool_mutex);ReleaseSemaphore(h_spool_full,1,NULL);ReleaseSemaphore(h_sendthread_to_mainthread,1,NULL);void print_space(int num) /显示若干个空格int i;for(i=0;inum;i+)printf( );void list_spool_queue() /列出打印请求队列char buffer10;WaitForSingleObject(h_spool_mutex,INFINITE);WaitForSingleObject(h_screen_mutex,INFINITE); system(cls);printf( number of files in the spool queue:%dnn,spool_buffer.spool_count);printf( spool queue n);printf(|-|-|-|n);printf(| index | filename | filesize(KB) |n);printf(|-|-|-|n);for(int i=0;iMAX_SPOOL;i+)printf(| %d,i);itoa(i, buffer, 10 );print_space(7-strlen(buffer);printf(| %s,spool_buffer.spool_queuei.file_name);print_space(36-strlen(spool_buffer.spool_queuei.file_name);printf(| %d,spool_buffer.spool_queuei.file_size);itoa(spool_buffer.spool_queuei.file_size,buffer,10);print_space(12-strlen(buffer);printf( |n);printf(|-|-|-|n);ReleaseMutex(h_spool_mutex);ReleaseMutex(h_screen_mutex);DWORD WINAPI spool_thread(LPVOID lpParameter) / 打印线程的线程函数while(1)WaitForSingleObject(h_semaphore_spool,INFINITE);WaitForSingleObject(h_spool_full,INFINITE); WaitForSingleObject(h_spool_mutex,INFINITE);WaitForSingleObject(h_screen_mutex,INFINITE);spool_buffer.spool_count-;printf(print a file in spool:nfilename:%sn,spool_buffer.spool_queuespool_buffer.spool_out.file_name);strcpy(spool_buffer.spool_queuespool_buffer.spool_out.file_name,);spool_buffer.spool_queuespool_buffer.spool_out.file_size=0;spool_buffer.spool_out=(spool_buffer.spool_out+1)%MAX_SPOOL;ReleaseMutex(h_screen_mutex);ReleaseMutex(h_spool_mutex);ReleaseSemaphore(h_spool_empty,1,NULL); ReleaseSemaphore(h_spoolthread_to_mainthread,1,NULL);return 0;int main(int argc,char *argv) / 主程序char select;h_send=CreateThread(NULL,0,sendthread,NULL,0,NULL);h_spool_thread=CreateThread(NULL,0,spool_thread,NULL,0,NULL);h_spool_mutex=CreateMutex(NULL,FALSE,NULL);h_screen_mutex=CreateMutex(NULL,FALSE,NULL);h_spool_full=CreateSemaphore(NULL,0,MAX_SPOOL,NULL);h_spool_empty=CreateSemaphore(NULL,MAX_SPOOL,MAX_SPOOL,NULL);h_print=CreateSemaphore(NULL,0,1,NULL);h_semaphore_spool=CreateSemaphore(NULL,0,1,NULL);h_sendthread_to_mainthread=CreateSemaphore(NULL,0,1,NULL);h_spoolthread_to_mainthread=CreateSemaphore(NULL,0,1,NULL);WaitForSingleObject(h_screen_mutex,INFINITE);while(1)printf
温馨提示
- 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
- 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
- 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
- 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
- 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
- 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
- 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。
最新文档
- 疫苗预防效果研究-洞察及研究
- 设备垫资合同(标准版)
- 餐饮门店装修合同(标准版)
- 转让居间协议合同(标准版)
- 2025年老年医学老年病诊治方案论证试卷答案及解析
- 2025年实验室检验结果解读与评估试题答案及解析
- 通风设备智能控制-洞察及研究
- 2025贵州毕节威宁自治县“特岗计划”教师招聘选岗及签约考试备考试题及答案解析
- 小学安全教育与管理计划
- 苏教版小学三年级下册数学学校教育协调计划
- JC-T 2586-2021 装饰混凝土防护材料
- DZ∕T 0227-2010 地质岩心钻探规程(正式版)
- 临床医学工程-题库
- SYT 0452-2021 石油天然气金属管道焊接工艺评定-PDF解密
- 屋顶分布式光伏发电项目EPC总承包工程招投标书范本
- 2000-2015年考研英语一真题及详细解析
- 体检中心礼仪培训课件
- 独立基础教学课件
- 20以内加减法口算题(10000道)(A4直接打印-每页100题)
- 会计从业资格基础知识汇总
- 项目干系人管理评估
评论
0/150
提交评论