Created
March 21, 2018 13:27
-
-
Save Geal/571a4a5be5fe23da3d5f7b8161deb9e7 to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#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