Finished Ex9.*
This commit is contained in:
parent
78d6fb4e3c
commit
d9d2d5f18f
4 changed files with 199 additions and 0 deletions
29
ex9.1/a.cpp
Executable file
29
ex9.1/a.cpp
Executable file
|
@ -0,0 +1,29 @@
|
||||||
|
#include <thread>
|
||||||
|
#include <string>
|
||||||
|
#include <iostream>
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Compile with 'g++ -pthread a.cpp'
|
||||||
|
*
|
||||||
|
* The order of printing is not well-defined
|
||||||
|
*/
|
||||||
|
|
||||||
|
using namespace std;
|
||||||
|
|
||||||
|
void f1() {
|
||||||
|
cout << "Hello ";
|
||||||
|
}
|
||||||
|
|
||||||
|
void f2(const std::string& s) {
|
||||||
|
cout << s << endl;
|
||||||
|
}
|
||||||
|
|
||||||
|
int main() {
|
||||||
|
thread t1(f1);
|
||||||
|
thread t2{f2, "Parallel World!"};
|
||||||
|
|
||||||
|
t1.join();
|
||||||
|
t2.join();
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
27
ex9.1/b.cpp
Executable file
27
ex9.1/b.cpp
Executable file
|
@ -0,0 +1,27 @@
|
||||||
|
|
||||||
|
#include <thread>
|
||||||
|
#include <string>
|
||||||
|
#include <iostream>
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Compile with 'g++ -pthread b.cpp'
|
||||||
|
*
|
||||||
|
* This gets an error 'terminate called without an active exception'
|
||||||
|
*/
|
||||||
|
|
||||||
|
using namespace std;
|
||||||
|
|
||||||
|
void f1() {
|
||||||
|
cout << "Hello ";
|
||||||
|
}
|
||||||
|
|
||||||
|
void f2(const std::string& s) {
|
||||||
|
cout << s << endl;
|
||||||
|
}
|
||||||
|
|
||||||
|
int main() {
|
||||||
|
thread t1(f1);
|
||||||
|
thread t2{f2, "Parallel World!"};
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
34
ex9.1/c.cpp
Executable file
34
ex9.1/c.cpp
Executable file
|
@ -0,0 +1,34 @@
|
||||||
|
|
||||||
|
#include <thread>
|
||||||
|
#include <string>
|
||||||
|
#include <iostream>
|
||||||
|
#include <chrono>
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Compile with 'g++ -pthread a.cpp'
|
||||||
|
*
|
||||||
|
* The order of printing is not well-defined
|
||||||
|
*/
|
||||||
|
|
||||||
|
using namespace std;
|
||||||
|
|
||||||
|
void f1() {
|
||||||
|
cout << "Hello " << endl;
|
||||||
|
this_thread::sleep_for(std::chrono::seconds(2));
|
||||||
|
cout << "World" << endl;
|
||||||
|
}
|
||||||
|
|
||||||
|
void f2() {
|
||||||
|
this_thread::sleep_for(std::chrono::seconds(1));
|
||||||
|
cout << "Parallel" << endl;
|
||||||
|
}
|
||||||
|
|
||||||
|
int main() {
|
||||||
|
thread t1(f1);
|
||||||
|
thread t2(f2);
|
||||||
|
|
||||||
|
t1.join();
|
||||||
|
t2.join();
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
109
ex9.2/main.cpp
Executable file
109
ex9.2/main.cpp
Executable file
|
@ -0,0 +1,109 @@
|
||||||
|
#include <thread>
|
||||||
|
#include <string>
|
||||||
|
#include <iostream>
|
||||||
|
#include <queue>
|
||||||
|
#include <random>
|
||||||
|
#include <chrono>
|
||||||
|
#include <mutex>
|
||||||
|
#include <condition_variable>
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Compile with 'g++ -pthread a.cpp'
|
||||||
|
*/
|
||||||
|
|
||||||
|
using namespace std;
|
||||||
|
|
||||||
|
std::mutex q_mutex;
|
||||||
|
std::mutex cout_mutex;
|
||||||
|
std::condition_variable q_cv;
|
||||||
|
|
||||||
|
void producer1( queue<int>& q, const int id ) {
|
||||||
|
// Make sure our cout does not cross some other thread's cout
|
||||||
|
cout_mutex.lock();
|
||||||
|
cout << "======================" << endl;
|
||||||
|
cout << " Starting Producer " << id << endl;
|
||||||
|
cout << "======================" << endl;
|
||||||
|
cout_mutex.unlock();
|
||||||
|
|
||||||
|
random_device d;
|
||||||
|
mt19937 mt(d());
|
||||||
|
int t_max = 3000;
|
||||||
|
uniform_int_distribution<> distr(0., t_max);
|
||||||
|
|
||||||
|
int n = 0;
|
||||||
|
|
||||||
|
while (true) {
|
||||||
|
n = distr(mt);
|
||||||
|
this_thread::sleep_for(chrono::milliseconds(n));
|
||||||
|
|
||||||
|
// Make sure our cout does not cross some other thread's cout
|
||||||
|
cout_mutex.lock();
|
||||||
|
cout << "Producer " << id << " : " << n << endl;
|
||||||
|
cout_mutex.unlock();
|
||||||
|
|
||||||
|
// Lock q so we can push a new element
|
||||||
|
std::unique_lock<std::mutex> q_lock(q_mutex);
|
||||||
|
q.push(n);
|
||||||
|
|
||||||
|
// Notify one of the consumers
|
||||||
|
q_cv.notify_one();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void consumer( queue<int>& q, const int id ) {
|
||||||
|
// Make sure our cout does not cross some other thread's cout
|
||||||
|
cout_mutex.lock();
|
||||||
|
cout << "======================" << endl;
|
||||||
|
cout << " Starting Consumer " << id << endl;
|
||||||
|
cout << "======================" << endl;
|
||||||
|
cout_mutex.unlock();
|
||||||
|
|
||||||
|
int b = 0;
|
||||||
|
while ( true ) {
|
||||||
|
{ // Scope the lock of the queue
|
||||||
|
std::unique_lock<std::mutex> q_lock(q_mutex);
|
||||||
|
|
||||||
|
while ( q.empty() ) {
|
||||||
|
// Wait until we get a signal from the condition variable
|
||||||
|
q_cv.wait(q_lock);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Get a value and pop it off
|
||||||
|
b = q.front();
|
||||||
|
q.pop();
|
||||||
|
}
|
||||||
|
|
||||||
|
// Make sure our cout does not cross some other thread's cout
|
||||||
|
cout_mutex.lock();
|
||||||
|
cout << " -- Consumer " << id << " : " << b << endl;
|
||||||
|
cout_mutex.unlock();
|
||||||
|
|
||||||
|
// Slow down this thread to have a race between the consumers and the producers
|
||||||
|
// This only works after we have successfully read an int
|
||||||
|
this_thread::sleep_for(chrono::milliseconds(2000));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
int main() {
|
||||||
|
|
||||||
|
queue<int> q;
|
||||||
|
|
||||||
|
|
||||||
|
thread cons1( consumer, std::ref(q), 1 ) ;
|
||||||
|
|
||||||
|
// make sure the consumer must have slept at least once
|
||||||
|
this_thread::sleep_for(chrono::seconds(2));
|
||||||
|
|
||||||
|
thread prod( producer1, std::ref(q), 1);
|
||||||
|
|
||||||
|
this_thread::sleep_for(chrono::seconds(5));
|
||||||
|
thread cons2( consumer, std::ref(q), 2) ;
|
||||||
|
|
||||||
|
|
||||||
|
prod.join();
|
||||||
|
cons1.join();
|
||||||
|
cons2.join();
|
||||||
|
cout << "Finishing up" << endl;
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
Reference in a new issue