Две очереди с ожиданием
Пытаюсь реализовать очередь (например, в какую-либо кассу) через односвязный список. Время прихода клиентов и время обработки запроса рандомится, т.е. оно совершенно случайное на каком-то промежутке времени. Вопрос: как сделать обработку клиентов от времени? Чтобы как только касса была свободна, первый элемент списка удалялся и ставился на обработку. Пытался найти везде примеры моделей работы касс в реальном времени, ничего не нашел. По сути пока что я попытался сделать две очереди из которых "если вошел - уже не вышел", поэтому реализованы только функции удаления с начала списка и добавление в конец
И две кассы: обе работают по-разному, поэтому и для каждого потока - своя функция Job, выполняющая работу.
Программа запускается, но вот функции Job1 и Job2 не работают, ибо значение GetSize() остается равным 0, несмотря на то, что список постепенно заполняется значениями. Как это исправить?
#include <iostream>
#include <time.h>
#include <string>
#include <thread>
#include <chrono>
#include <mutex>
#include <condition_variable>
#include <unistd.h>
using namespace std;
std::condition_variable cv;
mutex mtx;
double arrival_time = 0 ;
class List {
public:
List();
~List();
void pop_front();
void push_back(int data);
int getNum ();
void clear();
int GetSize() {return Size;};
private:
class Node {
public:
Node* pNext;
int data;
Node(int data = 0, Node *pNext = nullptr) {
this->data = data;
this->pNext = pNext;
}
};
int Size;
Node *head;
};
List::List(){
Size = 0;
head = nullptr;
}
List::~List() {
clear();
}
int List::getNum(){
int num = head->data;
return num;
}
void List::pop_front() {
if (head) {
Node *temp = head;
head = head->pNext;
delete temp;
Size--;
}
}
void List::push_back(int data) {
if (head == nullptr) {
head = new Node (data);
}
else {
Node *current = this->head;
while (current->pNext != nullptr) {
current = current->pNext;
}
current->pNext = new Node (data);
}
Size++;
}
void List::clear() {
while (Size) {
pop_front();
}
}
double uniform(double min, double max)
{
return (double)(rand())/RAND_MAX*(max - min) + min;
}
/*void Job1 (List z1, double arr_time1) {
mtx.lock();
t1 = arr_time1;
while (z1.GetSize()!=0) {
printf("В момент времени %.3f транзакт %d встал на выполнение ", t1, z1.getNum());
double worktime_1 = uniform(6, 26);
this_thread::sleep_for(std::chrono::duration<double, std::nano>(worktime_1));
double donetime_1 = t1 + worktime_1;
printf("В момент времени %.3f транзакт %d обработан ", donetime_1, z1.getNum());
t1 = donetime_1;
z1.pop_front();
}
mtx.unlock();
}*/
void Job1 (List z1, double arr_time1) {
double t1 = arr_time1;
mtx.lock();
while (arrival_time < 3600) {
double worktime_1 = uniform(6, 26);
while (z1.GetSize()==0)
this_thread::sleep_for(std::chrono::duration<double, std::nano>(1));
t1 = arrival_time;
printf("В момент времени %.3f транзакт %d встал на выполнение \n", t1, z1.getNum());
this_thread::sleep_for(std::chrono::duration<double, std::nano>(worktime_1));
double donetime_1 = t1 + worktime_1;
printf("В момент времени %.3f транзакт %d обработан \n", donetime_1, z1.getNum());
z1.pop_front();
t1 = donetime_1;
}
mtx.unlock();
}
void Job2 (List z2, double arr_time2) {
double t2 = arr_time2;
mtx.lock();
while (arrival_time < 3600) {
double worktime_2 = uniform(9, 26);
while (z2.GetSize()==0)
this_thread::sleep_for(std::chrono::duration<double, std::nano>(1));
t2 = arrival_time;
printf("В момент времени %.3f транзакт %d встал на выполнение \n", t2, z2.getNum());
this_thread::sleep_for(std::chrono::duration<double, std::nano>(worktime_2));
double donetime_2 = t2 + worktime_2;
printf("В момент времени %.3f транзакт %d обработан \n", donetime_2, z2.getNum());
z2.pop_front();
t2 = donetime_2;
}
mtx.unlock();
}
int main () {
List q1, q2;
srand((unsigned int)time(0));
thread th1(Job1, q1, arrival_time);
thread th2(Job2, q2, arrival_time);
int counter = 1;
while (arrival_time < 3600) {
double time = uniform(0,26);
arrival_time = arrival_time + time;
this_thread::sleep_for(std::chrono::duration<double, std::nano>(time));
printf("В момент времени %.3f транзакт %d встал в очередь ", arrival_time, counter);
if (q2.GetSize() < q1.GetSize()){
q2.push_back(counter);
cout << "2" << endl;
}
else {
q1.push_back(counter);
cout << "1" << endl;
//thread th1(Job1, q1, arrival_time);
//th1.join();
}
counter++;
}
q1.clear();
q2.clear();
th1.join();
th2.join();
return 0;
}