diff --git a/ex9.1/a.cpp b/ex9.1/a.cpp new file mode 100755 index 0000000..e87d915 --- /dev/null +++ b/ex9.1/a.cpp @@ -0,0 +1,29 @@ +#include +#include +#include + +/* + * 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; +} diff --git a/ex9.1/b.cpp b/ex9.1/b.cpp new file mode 100755 index 0000000..bb26cff --- /dev/null +++ b/ex9.1/b.cpp @@ -0,0 +1,27 @@ + +#include +#include +#include + +/* + * 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; +} diff --git a/ex9.1/c.cpp b/ex9.1/c.cpp new file mode 100755 index 0000000..a01e542 --- /dev/null +++ b/ex9.1/c.cpp @@ -0,0 +1,34 @@ + +#include +#include +#include +#include + +/* + * 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; +} diff --git a/ex9.2/main.cpp b/ex9.2/main.cpp new file mode 100755 index 0000000..f868d6f --- /dev/null +++ b/ex9.2/main.cpp @@ -0,0 +1,109 @@ +#include +#include +#include +#include +#include +#include +#include +#include + +/* + * 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& 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 q_lock(q_mutex); + q.push(n); + + // Notify one of the consumers + q_cv.notify_one(); + } +} + +void consumer( queue& 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 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 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; +}