-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathqueue_using_array.cpp
More file actions
147 lines (117 loc) · 3.34 KB
/
queue_using_array.cpp
File metadata and controls
147 lines (117 loc) · 3.34 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
#include <bits/stdc++.h>
#include <iostream>
#include <mutex>
#include <thread>
#include <condition_variable>
using namespace std;
#define SIZE 5
class Queue {
private:
int buffer[SIZE];
// int buffer2[SIZE];
// int* buffer = buffer1;
// Circular buffer implementation
// I will need a head and tail pointer along with remainder arithmetic to check where the head and tail is.
int head = 0, tail = 0, count = 0; // count >= SIZE -> buffer full ; count <= 0 -> buffer empty
// Linear Queue (Bounded)
// int front = -1;
// int rear = -1;
mutex mtx;
condition_variable not_empty;
condition_variable not_full;
public:
void enqueue(int value) {
// insert the value at the rear of the queue
unique_lock<mutex> lock(mtx);
// not_full.wait(lock, [&] {
// return rear < SIZE - 1; // check if the queue has space
// });
// if (front == -1) {
// front = 0;
// }
// rear++;
// buffer[rear] = value;
// Circular Buffer
not_full.wait(lock, [&] {
return count < SIZE; // check if the queue has space
});
buffer[tail] = value;
tail = (tail + 1) % SIZE;
count++;
lock.unlock();
not_empty.notify_one();
}
int dequeue() {
// remove the value from the front of the queue
unique_lock<mutex> lock(mtx);
// not_empty.wait(lock, [&] {
// return !isempty();
// });
// int value = buffer[front];
// if (front == rear) {
// front = rear = -1;
// } else {
// front++;
// }
not_empty.wait(lock, [&] {
return !isempty();
});
int value = buffer[head];
head = (head + 1) % SIZE;
count--;
lock.unlock();
not_full.notify_one();
return value;
}
int showfront() {
// display the front value of the queue
lock_guard<mutex> lock(mtx);
if (isempty()) {
return -1;
} else {
return buffer[head];
}
}
bool isempty() {
// check if the queue is empty
if (count <= 0) {
return true;
} else {
return false;
}
}
bool isfull() {
if (count >= SIZE) {
return true;
} else return false;
}
};
void producer(Queue& q, int id, int count) {
for (int i = 0; i < count; i++) {
int value = id * 100 + i;
q.enqueue(value);
cout << "Producer " << id << " enqueued " << value << endl;
this_thread::sleep_for(chrono::milliseconds(5));
}
}
void consumer(Queue& q, int id, int count) {
for (int i = 0; i < count; i++) {
int value = q.dequeue();
cout << "Consumer " << id << " dequeued " << value << endl;
this_thread::sleep_for(chrono::milliseconds(5));
}
}
int main() {
Queue q;
thread prod1(producer, ref(q), 1, 50);
thread cons1(consumer, ref(q), 1, 20);
thread prod2(producer, ref(q), 2, 10);
thread cons2(consumer, ref(q), 2, 40);
// cout << "Is queue empty? " << (q.isempty() ? "Yes" : "No") << endl;
prod1.join();
cons1.join();
prod2.join();
cons2.join();
cout << "All threads have finished execution." << endl;
return 0;
}