C++ multithreading + priority queue simulation printer task management

Effect picture:

  • When there is a high priority task in the print task, print it first
    Insert picture description here
  • When the number of copies of the print job exceeds the maximum capacity, it can also remember the number of printed copies
    Insert picture description here
  • When the number of tasks in the print queue does not exceed the maximum capacity
    Insert picture description here
  • A higher priority task appears when the print tasks are not all printed

Insert picture description here

  • When the priority of the print task is the same, print the one with less content first
    Insert picture description here
#include<stdio.h>
#include<iostream>
#include<queue>
#include<Windows.h>
#include<string>
#include<time.h>
using namespace std;
int error = 0;
int cnt = 0;//用来记录总任务数
int n;//用来记录当次输入的任务数量
int cur = 0;
int pre = 0;
CRITICAL_SECTION Printer; //定义Printer临界区资源变量
#define MAXSIZE  2 //打印队列的最大长度
struct Job {
    
    
    int id;//任务的序号
    int level;//任务的优先级
    int capacity;//打印内容的大小
    int amount = 0;
    string print_work;
};//任务结构体的创建
priority_queue<Job> work, q;
Job job[100000];
int done[100000];
DWORD thread_1, thread_2;
HANDLE hThread_1, hThread_2;
bool operator<(const Job& s1, const Job& s2) {
    
    
    if (s1.level == s2.level)//优先度相同返回打印内容少的
        return s1.capacity> s2.capacity;
    return s1.level < s2.level;//返回优先度高的任务
}
void lock()
{
    
    
    EnterCriticalSection(&Printer);
}
void unlock()
{
    
    
    LeaveCriticalSection(&Printer);
}
DWORD CALLBACK work_add(LPVOID param)
{
    
    
    while (!error)
    {
    
    
        lock();//work_add线程占用临界区资源
        {
    
    
            cout << "请输入需要添加的打印任务个数(输入0则打印完剩下任务)";
            cin >> n;
            cur =cur+n-pre;
            if (n == 0) //不再有新的打印任务
            {
    
    
                unlock();//停止占用临界区资源
                while (!work.empty())
                    Sleep(0);//如果打印队列中还有剩余的任务,则令work_print线程打印完所有剩余的任务
                error = 1;//跳出循环
                break;
            }
            for (int i = cnt; i < n + cnt; i++)
            {
    
    
                string st;
                job[i].id = i + 1;
                cout << "请输入第" << i + 1 << "个任务的优先级、打印份数、打印内容:";
                cin >> job[i].level >> job[i].amount;
                if (job[i].level > 7)
                    job[i].level = 7;
                getline(cin, st);//预防打印内容带有空格cin无法接收的情况
                job[i].print_work = st;
                job[i].capacity = job[i].print_work.size();//打印内容的大小
            }
            for (int i = cnt; i < n + cnt; i++)
            {
    
    
                cur+= job[i].amount-1;
                for (int j = 1; j <= job[i].amount; j++)
                {
    
    
                    q.push(job[i]);//将job的任务插入临时队列
                }
            }
           if (work.size()>0)
            {
    
    
               while (!work.empty())
               {
    
    
                   q.push(work.top());
                   work.pop();
               }

            }
            for (int i = 0; i < cur; i++) {
    
    
                if (work.size() == MAXSIZE) {
    
    //如果work打印队列满了
                    unlock();//停止占用临界区资源
                    while (work.size() == MAXSIZE)
                        Sleep(0);//让其他线程运行
                    lock();//再次占用临界区资源
                }
                work.push(q.top());//打印任务入队
                int x = q.top().id;
                q.pop();
                cout << "作业序号" << x << "进入打印队列准备打印" << endl;
            }
            cnt += n;//记录总任务数
        }
        unlock();//停止占用临界区资源
    }
    return 0;
}
DWORD CALLBACK work_print(LPVOID param)
{
    
    
    while (!error) 
    {
    
    
        lock();//work_print线程占用临界区资源
        {
    
    
            cout <<endl<< "开始打印........" << endl;
              while (!work.empty()) {
    
    //将当前work打印任务队列中所有任务打印完成
                auto t1 = clock();
                cout << "任务序号" << work.top().id << " 正在打印...";
                cout << '[';
                for (int i = 0; i < 100; i += 10)
                {
    
    
                    Sleep(work.top().capacity * 25);
                    cout << (char)0xa8 << (char)0x80;
                }
                auto t2 = clock();
                cout << "] 100%" << "  打印耗时:"<<(t2 - t1)/1000<<"s"<< endl;
                cout << "第"<<done[work.top().id]+1<< "份 "<< "任务序号" << work.top().id << " 打印完成:" << work.top().print_work << endl;
                done[work.top().id]++;
                work.pop();
                pre++;
            }
        }
        cout << "打印结束........" << endl << endl;
        unlock();
        while (work.empty())
            Sleep(0);
    }
    return 0;
}
void CreatePrinterThread()
{
    
    
    hThread_1 = CreateThread(NULL, 0, work_add, NULL, 0, &thread_1);
    if (hThread_1 == NULL)
    {
    
    
        cout << "线程创建失败..." << endl;
        error = 1;
        exit(error);
    }
    hThread_2 = CreateThread(NULL, 0, work_print, NULL, 0, &thread_2);
    if (hThread_2 == NULL)
    {
    
    
        cout << "线程创建失败..." << endl;
        error = 1;
        exit(error);
    }
}
int main()
{
    
    
    cout << "--------------------------欢迎使用打印机--------------------------" << endl;
    cout << " 注意事项:打印队列最大容量为:" << MAXSIZE << " 任务优先级为:1-7(数字越大越紧急)" << endl << endl;
    InitializeCriticalSection(&Printer);//初始化打印机临界区资源
    CreatePrinterThread();//开始创建添加任务、打印任务两条线程
    while (!error)
        Sleep(0);
    system("pause");
    cout << "--------------------------打印机已退出--------------------------" << endl;
    DeleteCriticalSection(&Printer);//摧毁打印机临界区资源
    return 0;
}

Guess you like

Origin blog.csdn.net/qq_43663263/article/details/105893545