栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > Java

假脱机打印程序与虚拟设备

Java 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

假脱机打印程序与虚拟设备

假脱机打印程序与虚拟设备 1、要求

利用多线程技术编写假脱机打印程序,并设计测试数据以验证程序的正确性。
1、界面要求:
程序采用简单的控制台界面,运行后在屏幕上显示功能菜单,列出该程序具有的功能,供用户选择。
2、功能要求:
(1)发送打印请求;
(2)查看假脱机打印队列;
(3)打印文件;
(4)退出。
用户选择功能后应该转到相应的处理程序,并在需要时显示程序的执行结果。
若用户选择(1)则提示用户输入待打印的文件名称,程序接收输入后将打印请求传送到打印队列中,并回到主菜单;
若用户选择(2)则在屏幕上列出打印队列情况,提示按任意键回到主界面;
若用户选择(3)则打印队首的文件,显示所打印的文件名称,按任意键回到主界面;
若用户选择(4)则退出程序的执行。

2、变量和函数的定义

需要两个数据结构,一个FILE_INFO用来描述打印请求,包括文件名称和文件大小。另一个数据结构SPOOL用来描述打印请求队列。

1、线程划分myfile

为了模拟假脱机打印程序,需要三个线程,主线程用于显示主菜单,接收用户的功能选择,显示打印队列情况;打印请求接收/发送线程接收用户的打印请求,并将打印请求存放到打印请求队列;打印线程用来从打印队列中取文件并将其输出到屏幕。

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是打印线程和打印请求接收/发送线程之间的同步信号量。
该程序共有五个函数。

sendthread()	//接收用户的打印请求并将其发送到打印请求队列中
spool_thread()	  //从打印请求队列中取待打印文件并将其输出到屏幕上
print_space()  	//显示若干个空格
list_spool_queue()	//列出打印队列
main()	  //创建线程,初始化信号量,显示主菜单,根据用户选择执行相应功能

上面变量看的很混乱?没关系,直接看代码

#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include 
using namespace std;

HANDLE h_send;  //申明打印请求接收/发送线程
HANDLE h_spool_thread;  //申明打印线程
pthread_mutex_t h_screen_mutex;  //对控制台终端的互斥变量
pthread_mutex_t h_spool_mutex;  //对打印请求队列的互斥变量
HANDLE h_print;  //主线程要通知打印请求接收/发送线程开始接收用户请求的信号量
HANDLE h_sendthread_to_mainthread;  //主线程要等待打印请求接收/发送线程发来接收完毕的信号量
HANDLE h_semaphore_spool;  //主线程要通知打印线程开始打印文件的信号量
HANDLE h_spolthread_to_mainthread;  //主线程要等待打印线程发来打印完毕的信号量
HANDLE h_spool_empty;  //显示空位置
HANDLE h_spool_full;  //显示打印请求个数
int con_request=0;  //请求打印时spool_queue数组的下标
int con_printf=0;  //进行打印时spool_queue数组的下标
struct FILE_INFO{  //描述打印请求的结构体
    string file_name;  //文件名称
    int file_size;  //文件大小
};

struct SPOOL{  //描述打印请求队列
    int spool_count=0;  //打印队列中的个数
    int spool_in=0;  //记录下一个打印请求存放的存储位置
    int spool_out=0;  //记录下一个被打印文件的存储位置
    FILE_INFO spool_queue[5];  //打印队列中的文件的名称和大小
}spool_buffer;

void list_spool_queue(){
    pthread_mutex_lock(&h_spool_mutex);
    pthread_mutex_lock(&h_screen_mutex);
    system("CLS");
    printf("|序 号|---文件名---|---文件大小---|n");
    for(int i=0;i<5;i++){
        cout<<"|  "<
    while(1){
        WaitForSingleObject(h_print,INFINITE);  //主线程发送的申请打印接收完毕
        system("CLS");
        if(WaitForSingleObject(h_spool_empty,5)==WAIT_TIMEOUT){ //判断有无空位置
            printf("没有空位置了!!!请重新选择nn");
        }
        else{
            pthread_mutex_lock(&h_screen_mutex);
            system("CLS");
            string name;
            printf("请输入你要打印的文件名称:");
            getline(cin,name);
            pthread_mutex_unlock(&h_screen_mutex);
            int size=rand()%10;
            printf("n文件大小为%dn",size);
            pthread_mutex_lock(&h_spool_mutex);
            spool_buffer.spool_count++;
            spool_buffer.spool_in+=size;
            spool_buffer.spool_queue[con_request].file_name=name;
            spool_buffer.spool_queue[con_request].file_size=size;
            con_request++;
            con_request=con_request%5;
            if(con_request==0){
                spool_buffer.spool_in=0;
            }
            ReleaseSemaphore(h_spool_full,1,NULL);  //文件数加一
            pthread_mutex_unlock(&h_spool_mutex);
        }
        ReleaseSemaphore(h_spolthread_to_mainthread,1,NULL);  //通知主线程申请完毕
    }
}

void spool_thread(){
    while(1){
        WaitForSingleObject(h_semaphore_spool,INFINITE);  //主线程发送的打印请求接收完毕
        if(WaitForSingleObject(h_spool_full,0)==WAIT_TIMEOUT){
            printf("nn没有文件可打印!!!请重新输入n");
        } 
        else{
            pthread_mutex_lock(&h_spool_mutex);
            pthread_mutex_lock(&h_screen_mutex);
            spool_buffer.spool_count--;
            cout<
                spool_buffer.spool_out=0;
            }
            pthread_mutex_unlock(&h_screen_mutex);
            pthread_mutex_unlock(&h_spool_mutex);
            ReleaseSemaphore(h_spool_empty,1,NULL);  //空位置加一
        }
        ReleaseSemaphore(h_spolthread_to_mainthread,1,NULL);  //通知主线程打印完毕
    }
}

int main(){
    pthread_mutex_init(&h_screen_mutex,NULL);  //对互斥变量和同步变量初始化
    pthread_mutex_init(&h_spool_mutex,NULL);
    h_print=CreateSemaphore(NULL,0,1,NULL);  //初始值为0,最大值为1
    h_sendthread_to_mainthread=CreateSemaphore(NULL,0,1,NULL);
    h_semaphore_spool=CreateSemaphore(NULL,0,1,NULL);
    h_spolthread_to_mainthread=CreateSemaphore(NULL,0,1,NULL);
    h_spool_empty=CreateSemaphore(NULL,5,5,NULL);  //初始值为5,最大值为5
    h_spool_full=CreateSemaphore(NULL,0,5,NULL);  //初始值为0,最大值为5
    h_send=CreateThread(NULL,0,(LPTHREAD_START_ROUTINE)(sendthread),NULL,0,NULL);  //创建线程
    h_spool_thread=CreateThread(NULL,0,(LPTHREAD_START_ROUTINE)(spool_thread),NULL,0,NULL);  //创建线程
    for(int i=0;i<5;i++){  //初始化
        spool_buffer.spool_queue[i].file_name=' ';
        spool_buffer.spool_queue[i].file_size=0;
    }
    char iin;
    bool end=1;
    while(end){
        pthread_mutex_lock(&h_screen_mutex);
        printf("|------------------菜单显示------------------|n");
        printf("|-----------1.发送打印请求-------------------|n");
        printf("|-----------2.查看假脱机打印队列-------------|n");
        printf("|-----------3.打印文件-----------------------|n");
        printf("|-----------4.退出---------------------------|n");
        printf("|-----------请输入你要执行的操作(1-4):-------|n");
        scanf("%c",&iin);
        getchar();
        system("CLS");
        pthread_mutex_unlock(&h_screen_mutex);
        switch (iin){
            case '1':
                ReleaseSemaphore(h_print,1,NULL);  //唤醒申请打印请求
                WaitForSingleObject(h_spolthread_to_mainthread,INFINITE);  //线程发来的请求完毕的信号接收完毕
                break;
            case '2':
                list_spool_queue(); //全部显示
                break;
            case '3':
                ReleaseSemaphore(h_semaphore_spool,1,NULL);  //唤醒打印
                WaitForSingleObject(h_spolthread_to_mainthread,INFINITE);  //线程发来的打印完毕的信号接受完毕
                break;
            case '4':
                end=0;
                break;
        }
    }
    system("pause");
    return 0;
}
转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/937802.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号