利用(循环队列)和(多线程编程)模拟实现打印作业任务管理

描述

循环队列存放需要打印的作业任务,并用多线程的方式分别对临界区进行添加作业和打印作业。

具体思路

  1. 创建临界区对象和两个子线程。一个子线程调用的作为参数的函数用于向队列中添加作业;另一个子线程则取出队首任务并打印。
  2. 当队列满时,向队列中添加作业的子线程会陷入阻塞,等待打印线程的执行;而当队列空时,打印线程就会陷入阻塞,等待向队列添加作业的线程执行。
  3. 在退出程序前需要进行扫尾工作(打印完剩下的作业)。
  4. 在整个程序执行过程中,主进程需要保持阻塞。否则主进程结束,子线程即使未执行完也会结束。

CreateThread()

线程创建函数说明:

CreateThread(
_In_opt_LPSECURITY_ATTRIBUTES lpThreadAttributes,
_In_SIZE_T dwStackSize,
_In_LPTHREAD_START_ROUTINE lpStartAddress,
_In_opt_drv_aliasesMemLPVOID lpParameter,
_In_DWORD dwCreationFlags,
_Out_opt_LPDWORD lpThreadId
);

参数说明:1

  • lpThreadAttributes:指向SECURITY_ATTRIBUTES型态的结构的指针。在Windows 98中忽略该参数。在Windows NT中,NULL使用默认安全性,不可以被子线程继承,否则需要定义一个结构体将它的bInheritHandle成员初始化为TRUE
  • dwStackSize,设置初始栈的大小,以字节为单位,如果为0,那么默认将使用与调用该函数的线程相同的栈空间大小。任何情况下,Windows根据需要动态延长堆栈的大小。
  • lpStartAddress,指向线程函数的指针,形式:@函数名,函数名称没有限制。
  • lpParameter:向线程函数传递的参数,是一个指向结构的指针,不需传递参数时,为NULL。
  • dwCreationFlags :线程标志,可取值如下
    (1)CREATE_SUSPENDED(0x00000004):创建一个挂起的线程,
    (2)0:表示创建后立即激活。
    (3)STACK_SIZE_PARAM_IS_A_RESERVATION(0x00010000):dwStackSize参数指定初始的保留堆栈 的大小,否则,dwStackSize指定提交的大小。该标记值在Windows 2000/NT and Windows Me/98/95上不支持。
  • lpThreadId:保存新线程的id。
    返回值:函数成功,返回线程句柄;函数失败返回false。若不想返回线程ID,设置值为NULL。

临界区操作函数

下面是一些对临界区操作的主要函数:

  • InitializeCriticalSection (LPCRITICAL_SECTION lpCriticalSection); 初始化临界区对象
  • DeleteCriticalSection (LPCRITICAL_SECTION lpCriticalSection); 销毁临界区对象
  • EnterCriticalSection (LPCRITICAL_SECTION lpCriticalSection); 进入临界区
  • LeaveCriticalSection (LPCRITICAL_SECTION lpCriticalSection); 离开临界区

函数EnterCriticalSectionLeaveCriticalSection中间的代码表示临界区代码,必须成对出现,否则会出现死锁的现象。
如果已经有线程进入了临界区,其他线程调用EnterCriticalSection则会被阻塞,并使线程进入休眠状态,直到进入临界区的线程离开,同时处理器调度该线程进入临界区,该线程才会被唤醒并进入临界区。

实现代码

#include<stdio.h>
#include<iostream>
#include "Windows.h"
int my_exit = 0;
CRITICAL_SECTION my_printer;    //创建临界区对象

typedef int QElemType;
#define MAXSIZE  3 

typedef struct {
   
	QElemType *base;
	int front;   
	int rear;  
	int tag;
    bool isEmpty() {
   
        return front == rear && tag == 0;
    }
    bool isFull() {
   
        return front == rear && tag == 1;
    }
    QElemType hw;   //作业序号
}CirQueue;

int InitQueue (</
  • 6
    点赞
  • 26
    收藏
    觉得还不错? 一键收藏
  • 4
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值