#include <unistd.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include<time.h>
#include <sys/sem.h>
#include <condition_variable>
#include <iostream>
#include <mutex>
#include <thread>
#include <vector>
#include <queue>
#include <stdio.h>
#include <stdlib.h>
#include <pthread.h>
#include <stack>
#include "../header/header.h"
using namespace std;
pthread_mutex_t mutx = PTHREAD_MUTEX_INITIALIZER;
union semun {
int val; /* value for SETVAL */
struct semid_ds *buf; /* buffer for IPC_STAT, IPC_SET */
unsigned short *array; /* array for GETALL, SETALL */
struct seminfo *__buf; /* buffer for IPC_INFO */
};
class Task{
private:
string name;
double size;
int priority;
public:
bool operator<(const Task& task) const{
if(this->priority == task.priority){
return this->size > task.size;
}
else{
return this->priority > task.priority;
}
}
Task(const string &name, double size, int priority) : name(name), size(size), priority(priority) {}
const string &getName() const {
return name;
}
void setName(const string &name) {
Task::name = name;
}
double getSize() const {
return size;
}
void setSize(double size) {
Task::size = size;
}
int getPriority() const {
return priority;
}
Task() {
this->priority = 0;
this->size = 0;
this->name = "";
}
void setPriority(int prior) {
Task::priority = prior;
}
};
class PrintQueue{
public:
void push(Task task){
this->printqueue.push(task);
}
Task top(){
return this->printqueue.top();
}
void pop(){
this->printqueue.pop();
}
size_t size(){
return this->printqueue.size();
}
bool empty(){
return this->printqueue.empty();
}
private:
priority_queue<Task> printqueue;
};
int key;
int semid;
union semun arg;
int flag ;
PrintQueue printQueue;
int ret;
int print_ret;
/***对信号量数组semnum编号的信号量做P操作***/
int P(int semid, int semnum)
{
struct sembuf sops={semnum,-1, SEM_UNDO};
return (semop(semid,&sops,1));
}
/***对信号量数组semnum编号的信号量做V操作***/
int V(int semid, int semnum)
{
struct sembuf sops={semnum,+1, SEM_UNDO}; // semundo避免造成死锁
return (semop(semid,&sops,1));
}
void InsertTask(Task& task){
if(pthread_mutex_lock(&mutx) != 0)
{
perror("pthread_mutex_lock");
exit(EXIT_FAILURE);
}
// 加锁成功
if (P(semid, 0) < 0)
{
perror("P operate error,资源未上锁") ;
return;
}
// cout << "获取锁了,正在进行插入" << endl;
printQueue.push(task);
cout << "正在添加该任务" << endl;
for(int i=0;i<50;i++)
{
sleep(0.01);
cout << (char)0xa8 << (char)0x80;
}
cout << endl;
// cout << "释放" << endl;
if(pthread_mutex_unlock(&mutx) != 0)
{
perror("pthread_mutex_unlock");
exit(EXIT_FAILURE);
}
//退锁
if (V(semid, 0) < 0)
{
perror("P operate error,资源未释放") ;
return;
}
}
// 删除打印任务,同时必须使其他试图执行打印以及添加任务的线程阻塞
void delete_task(string name){
if (P(semid, 0) < 0)
{
perror("P operate error,其他进程未休眠");
return;
}
if(pthread_mutex_lock(&mutx) != 0)
{
perror("pthread_mutex_lock");
exit(EXIT_FAILURE);
}
queue<Task> temp_queue;
bool if_found = false;
cout << "正在删除名称为" << name << "的打印任务" << endl;
for (size_t i = 0; i < printQueue.size(); ++i) {
if(printQueue.top().getName() == name)
{
if_found = true;
printQueue.pop();
break;
}
temp_queue.push(printQueue.top());
printQueue.pop();
}
if(!temp_queue.empty())
{
printQueue.push(temp_queue.front());
temp_queue.pop();
}
if(!if_found)
{
cout << "未找到对应的打印任务"<<endl;
}
else{
cout << "删除成功" << endl;
}
if(pthread_mutex_unlock(&mutx) != 0)
{
perror("pthread_mutex_unlock");
exit(EXIT_FAILURE);
}
if (V(semid, 0) < 0)
{
perror("V operate error,其他进程未唤醒") ;
return ;
}
}
void DoPrint(){
if (P(semid, 0) < 0)
{
perror("P operate error,其他进程未休眠") ;
return ;
}
if(pthread_mutex_lock(&mutx) != 0)
{
perror("pthread_mutex_lock");
exit(EXIT_FAILURE);
}
while(!printQueue.empty())
{
Task task = printQueue.top();
cout << "正在打印" << task.getName() << "的内容," << "大小为" << task.getSize() << "KB" << endl;
cout << "[";
auto t1 = clock();
for(int i=0;i<10;i++)
{
sleep(1);
cout << (char)0xa8 << (char)0x80;
}
auto t2 = clock();
cout << "] 100%" <<endl;
cout << "打印耗时" << (t2 - t1) << "ms"<< endl;
printQueue.pop();
}
if (V(semid, 0) < 0)
{
perror("P operate error,其他进程未唤醒") ;
return ;
}
if(pthread_mutex_unlock(&mutx) != 0)
{
perror("pthread_mutex_unlock");
exit(EXIT_FAILURE);
}
//释放锁
}
void Print_Ongoing_Task(){
if (P(semid, 0) < 0)
{
perror("P operate error,其他进程未休眠") ;
return ;
}
if(pthread_mutex_lock(&mutx) != 0)
{
perror("pthread_mutex_lock failed");
exit(EXIT_FAILURE);
}
PrintQueue temp_queue;
size_t size = printQueue.size();
for (int i = 0; i < size; ++i) {
printf("第%d个打印任务是%s,大小为%f KB,优先级为%d",i,printQueue.top().getName().c_str(),printQueue.top().getSize(),printQueue.top().getPriority());
temp_queue.push(printQueue.top());
sleep(1);
cout << " 未打印" << endl;
printQueue.pop();
}
printQueue = temp_queue;
if(pthread_mutex_unlock(&mutx) != 0)
{
perror("pthread_mutex_unlock failed");
exit(EXIT_FAILURE);
}
if (V(semid, 0) < 0)
{
perror("P operate error,其他进程未唤醒") ;
return ;
}
}
void showstatus(){
ret =semctl(semid,0,GETVAL,arg);
if(ret == 0)
{
cout << "打印机正在被使用!" << endl;
}
else{
cout << "打印机无人使用" << endl;
}
}
int main(int argc, char **argv)
{
struct sembuf semop;
key = ftok("/tmp", 0x66 ) ;
if ( key < 0 )
{
perror("ftok key error") ;
return -1 ;
}
semid = semget(key,3,IPC_CREAT|0600);
if (semid == -1)
{
perror("create semget error");
return 0;
}
if ( argc == 1 )
{
arg.val = 1;
/***对0号信号量设置初始值***/
ret =semctl(semid,0,SETVAL,arg);
if (ret < 0 )
{
perror("ctl sem error");
semctl(semid,0,IPC_RMID,arg);
return -1 ;
}
}
cout << "程序初始化: ";
system("date");
string name;;
double size;
int prior;
Task task;
pid_t pid;
key_t key_n ;
int shm_id;
void *shm = NULL;
char buf[1024+1];
// printQueue* printque;
if((key_n = ftok("/",'s')<0)) //生成共享内存的key值
{
perror("Fail to ftok");
exit(EXIT_SUCCESS);
}
printf("key num:%d\n",key_n);
// if((shm_id = shmget(key_n,1024,0666|IPC_CREAT))==-1) //创建共享内存
// {
// perror("Fail to shmget");
// exit(EXIT_SUCCESS);
// }
while(true){
cout << "请输入你要进行的操作: 1:新增打印任务; 2: 删除打印任务; 3:查看打印任务完成情况 ;4: 开始打印; 5: 展示打印机状态"<< endl;
int cmd;
cin >> cmd;
switch (cmd) {
case 1:
cout << "请输入名字"<<endl;
cin >>name;
cout <<"请输入大小"<<endl;
cin >> size;
cout << "请输入优先级"<< endl;
cin >>prior;
task = Task(name,size,prior);
pid = fork();
if(pid < 0)
{
perror("fork"); //错误处理
exit(1);
}
else if(pid == 0)
{
InsertTask(task);
}
else
{
int status = 0;
pid_t res = waitpid(pid, &status, 0); //阻塞式等待
if(res > 0) //等待子进程运行成功
{
printf("\n");
// printf("插入程序运行结果 Running Code: %d \n", WEXITSTATUS(status));
}
}
break;
case 2:
cout <<"请输入你要删除的打印任务的名称" <<endl;
cin >> name;
pid = fork();
if(pid < 0)
{
perror("fork"); //错误处理
exit(1);
}
else if(pid == 0)
{
delete_task(name);
}
else
{
int status = 0;
pid_t res = waitpid(-1, &status, 0); //阻塞式等待
if(res > 0) //等待子进程运行成功
{
printf("\n");
// printf("删除程序运行结果 Running Code: %d \n", WEXITSTATUS(status));
}
}
break;
case 3:
pid = fork();
if(pid < 0)
{
perror("fork"); //错误处理
exit(2);
}
else if(pid == 0)
{
Print_Ongoing_Task();
}
else
{
int status = 0;
pid_t res = waitpid(-1, &status, 0); //阻塞式等待
// if(res > 0) //等待子进程运行成功
// {
// printf("\n");
// // printf("观察打印队列程序运行结果 Running Code: %d \n", WEXITSTATUS(status));
// }
}
break;
case 4:
pid = fork();
if(pid < 0)
{
perror("fork"); //错误处理
exit(1);
}
else if(pid == 0)
{
DoPrint();
}
else
{
int status = 0;
pid_t res = waitpid(-1, &status, 0); //阻塞式等待
if(res > 0) //等待子进程运行成功
{
printf("\n");
// printf("打印程序运行结果 Running Code: %d \n", WEXITSTATUS(status));
}
}
break;
case 5:
pid = fork();
if(pid < 0)
{
perror("fork"); //错误处理
exit(1);
}
else if(pid == 0)
{
showstatus();
}
else
{
int status = 0;
pid_t res = waitpid(-1, &status, 0); //阻塞式等待
if(res > 0) //等待子进程运行成功
{
printf("\n");
// printf("打印程序运行结果 Running Code: %d \n", WEXITSTATUS(status));
}
}
break;
default:
cout << "请输入正确指令" << endl;
break;
}
}
if ( argc >1 )
{
semctl(semid,0,IPC_RMID,arg); //删除信号量集合
}
return 0 ;
}
sdasdasd
最新推荐文章于 2024-11-11 19:42:06 发布