Writing a code which is kind of model of 2-cashiers. Each cashier has his own time of doing work which is double and randomed in [a,b]
interval. My problem is in line 42
or so: my code does like 1 or 2 or 3 iterations and then only queue is growing up. No items deleted. So in interval of an hour (I've identified it as an 3600 microseconds to syncronize threads) we have output like that:
In a time moment of 2.648 process 1 is in a queue 1
In a time moment of 4.419 process 2 is in a queue 2
In a time moment of 21.593 process 3 is in a queue 3
In a time moment of 21.868 process 4 is in a queue 4
... etc till 3600
What should I do to syncronize my threads to make my program work correct? Cashiers in two different threads should process their clients and output time of adding element in queue/starting of work with element/ending of work with element in console. Please help! Only started to learn how threads are working and have no idea for 2 days already.
#include <iostream>
#include <time.h>
#include <string>
#include <thread>
#include <chrono>
#include <mutex>
#include <queue>
#include <condition_variable>
#include <unistd.h>
using namespace std;
double arrival_time = 0 ;
double uniform(double min, double max)
{
return (double)(rand())/RAND_MAX*(max - min) + min;
}
class Cashier {
private:
int q_num;
double min;
double max;
bool status; // true - свободен, false - занят
std::mutex mtx;
std::condition_variable cv;
public:
Cashier(double a, double b, int n) { min = a; max = b; status = true; q_num = n;};
void Job();
void Waiting();
void counter();
queue<int> q;
};
double getTime () {
return arrival_time;
}
void Cashier::Job(){
bool ifTime = false;
double t2;
while (arrival_time < 3600) {
std::unique_lock <std::mutex> ul (mtx);
cv.wait(ul, [this]{return ( (q.empty() == 0) && (status == true) ) ? true : false ;});
if (ifTime == false) {t2 = getTime();}
printf("In a time moment of %.3f process %d started working
", t2, q.front());
status = false;
double worktime = uniform(min, max);
this_thread::sleep_for(std::chrono::duration<double, std::nano>(worktime));
double endtime = t2 + worktime;
printf("In a time moment of %.3f process %d ended work
", endtime, q.front());
q.pop();
if (q.empty() == 0) {t2 = endtime; ifTime = true;} else {ifTime = false;}
status = true;
cv.notify_one();
}
//ul.unlock();
}
/*void Cashier::Waiting() {
std::unique_lock<mutex> lg (mtx);
while (arrival_time < 3600) {
if (q.empty() == true) {
Waiting();
}
if (status == false) {
Waiting();
}
cv.notify_one();
}
}*/
void Cashier::Waiting() {
while (arrival_time < 3600) {
std::unique_lock<mutex> ul (mtx);
cv.wait(ul, [this]{return (status == true) ? true : false ;});
if (q.empty() == 0)
cv.notify_one();
else Waiting();
}
}
int main () {
srand((unsigned int)time(0));
int counter = 1;
Cashier q1(6, 26, 1);
Cashier q2(9, 26, 2);
thread th1 ([&](){
q1.Job();
q1.Waiting();
});
thread th2 ([&](){
q2.Job();
q2.Waiting();
});
while (arrival_time < 3600) {
double time = uniform (0, 26);
arrival_time += time;
this_thread::sleep_for(std::chrono::duration<double, std::nano>(time));
printf("In a time moment of %.3f process %d is in a queue ", arrival_time, counter);
(q2.q.size() < q1.q.size()) ? cout << "2
" : cout << "1
";
if (q2.q.size() < q1.q.size()) {
q2.q.push(counter);
}
else {
q1.q.push(counter);
}
counter++;
}
th1.join();
th2.join();
return 0;
}
与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…