Skip to content

Instantly share code, notes, and snippets.

@Geal
Created March 21, 2018 13:27
Show Gist options
  • Save Geal/571a4a5be5fe23da3d5f7b8161deb9e7 to your computer and use it in GitHub Desktop.
Save Geal/571a4a5be5fe23da3d5f7b8161deb9e7 to your computer and use it in GitHub Desktop.
#include <condition_variable>
#include <mutex>
#include <thread>
#include <iostream>
#include <queue>
#include <chrono>
using namespace std;
class Queue {
public:
int pop() {
unique_lock<std::mutex> mlock(mutex);
while (queue.empty()) {
cond.wait(mlock);
}
int item = queue.front();
queue.pop();
cond.notify_one();
return item;
}
void push(const int item) {
unique_lock<std::mutex> mlock(mutex);
while (queue.size() >= 10) {
printf("queue full, waiting\n");
cond.wait(mlock);
}
queue.push(item);
mlock.unlock();
cond.notify_one();
}
bool try_pop(int& res) {
unique_lock<std::mutex> mlock(mutex);
if (queue.empty()) {
return false;
} else {
int item = queue.front();
queue.pop();
cond.notify_one();
res = item;
return true;
}
}
int size() {
return queue.size();
}
private:
std::queue<int> queue;
std::mutex mutex;
std::condition_variable cond;
};
void client(int id, Queue* client_server, Queue* server_client) {
int counter = 0;
while(true) {
std::this_thread::sleep_for(std::chrono::milliseconds(100));
client_server->push(counter);
int res = server_client->pop();
printf("client[%d] sent %d and received %d", id, counter, res);
counter +=1;
}
}
void worker(int id, Queue* worker_server, Queue* server_worker) {
int counter = 0;
while(true) {
std::this_thread::sleep_for(std::chrono::milliseconds(100));
int value = server_worker->pop();
worker_server->push(value + counter);
printf("worker[%d] received %d and sent %d", id, value, value + counter);
counter +=1;
}
}
int main() {
int num_clients = 10;
int num_workers = 5;
std::thread clients[num_clients];
std::thread workers[num_workers];
Queue* client_server[num_clients];
Queue* server_client[num_clients];
Queue* worker_server[num_workers];
Queue* server_worker[num_workers];
for (int i = 0; i < num_workers; ++i) {
worker_server[i] = new Queue();
server_worker[i] = new Queue();
workers[i] = std::thread(worker, i, worker_server[i], server_worker[i]);
}
for (int i = 0; i < num_clients; ++i) {
client_server[i] = new Queue();
server_client[i] = new Queue();
clients[i] = std::thread(client, i, client_server[i], server_client[i]);
}
// server part
while(true) {
}
for (int i = 0; i < num_clients; ++i) {
clients[i].join();
}
for (int i = 0; i < num_workers; ++i) {
workers[i].join();
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment