Parent directory
async.cpp
concur.cpp
cond-var.cpp
future1.cpp
future2.cpp
Makefile
pthread.cpp
#include <iostream>
#include <future>
using namespace std;
int main() {
future<int> score_future = async(launch::async,
[] {
string line;
int attempts = 0;
cin.exceptions(ios::failbit | ios::badbit);
do {
cout << "Guess my word: ";
getline(cin, line);
++attempts;
} while (line != "banana");
return attempts;
}
);
try {
int final_score = score_future.get();
cout << "It took you " << final_score << " attempts!\n";
} catch (const exception& e) {
cout << "Exception from worker thread: " << e.what() << '\n';
}
}#include <iostream>
#include <chrono>
#include <thread>
#include <mutex>
using namespace std;
using namespace std::chrono;
struct wallet {
mutex m;
uint64_t money = 0;
operator uint64_t() const { return money; }
wallet& operator++() {
m.lock();
++money;
m.unlock();
// {
// scoped_lock lck{m};
// ++money;
// }
return *this;
}
};
void f(wallet& sum, uint64_t count) {
while (count--) {
++sum;
}
}
int main() {
constexpr uint64_t count = 1'000'000;
wallet sum;
auto time0 = high_resolution_clock::now();
thread t1 { f, ref(sum), count };
thread t2 { f, ref(sum), count };
t1.join();
t2.join();
// {
// jthread t1 { f, ref(sum), count };
// jthread t2 { f, ref(sum), count };
// }
auto time1 = high_resolution_clock::now();
auto dt = duration_cast<microseconds>(time1 - time0);
cout << "elapsed: " << dt.count() << " microsec\n";
cout << "result: " << sum << '\n';
}#include <iostream>
#include <thread>
#include <mutex>
#include <condition_variable>
using namespace std;
int main() {
mutex mtx;
condition_variable done;
int final_score = 0;
jthread t {
[&]() {
string line;
int attempts = 0;
do {
cout << "Guess my word: ";
getline(cin, line);
++attempts;
} while (line != "banana");
{
unique_lock lck(mtx);
final_score = attempts;
done.notify_one();
}
}
};
{
unique_lock lck(mtx);
while (final_score == 0) {
done.wait(lck);
}
// Instead of the while loop, we could write this:
// done.wait(lck, [&] { return final_score != 0; });
cout << "It took you " << final_score << " attempts!\n";
}
}#include <iostream>
#include <future>
#include <thread>
using namespace std;
int main() {
promise<int> score_promise;
future<int> score_future = score_promise.get_future();
jthread t {
[&score_promise]() {
string line;
int attempts = 0;
do {
cout << "Guess my word: ";
getline(cin, line);
++attempts;
} while (line != "banana");
score_promise.set_value(attempts);
}
};
int final_score = score_future.get();
cout << "It took you " << final_score << " attempts!\n";
}#include <iostream>
#include <future>
#include <thread>
#include <exception>
using namespace std;
int main() {
promise<int> score_promise;
future<int> score_future = score_promise.get_future();
jthread t {
[&score_promise]() {
string line;
int attempts = 0;
cin.exceptions(ios::failbit | ios::badbit);
try {
do {
cout << "Guess my word: ";
getline(cin, line);
++attempts;
} while (line != "banana");
score_promise.set_value(attempts);
} catch (...) {
score_promise.set_exception(current_exception());
}
}
};
try {
int final_score = score_future.get();
cout << "It took you " << final_score << " attempts!\n";
} catch (const exception& e) {
cout << "Exception from worker thread: " << e.what() << '\n';
}
}CC = g++
CXX = g++
CFLAGS = -Wall -g
CXXFLAGS = -Wall -g -std=c++20 -pthread
LDFLAGS = -pthread
LDLIBS =
executables = pthread concur cond-var future1 future2 async
.PHONY: default
default: $(executables)
pthread: pthread.o
concur: concur.o
cond-var: cond-var.o
future1: future1.o
future2: future2.o
async: async.o
.PHONY: clean
clean:
rm -f a.out core *.o $(executables)
.PHONY: all
all: clean default#include <iostream>
#include <chrono>
#include <pthread.h>
using namespace std;
using namespace std::chrono;
struct Args {
uint64_t* sum_ptr;
uint64_t count;
};
void* f1(void* args) {
Args* p = (Args*)args;
uint64_t* sum_ptr = p->sum_ptr;
uint64_t count = p->count;
while (count--) {
++*sum_ptr;
}
return NULL;
}
pthread_mutex_t mtx = PTHREAD_MUTEX_INITIALIZER;
void* f2(void* args) {
Args* p = (Args*)args;
uint64_t* sum_ptr = p->sum_ptr;
uint64_t count = p->count;
while (count--) {
pthread_mutex_lock(&mtx);
++*sum_ptr;
pthread_mutex_unlock(&mtx);
}
return NULL;
}
uint64_t sum1() {
constexpr uint64_t count = 1'000'000;
uint64_t sum = 0;
Args args1 { &sum, count };
f1(&args1);
Args args2 { &sum, count };
f1(&args2);
return sum;
}
uint64_t sum2() {
constexpr uint64_t count = 1'000'000;
uint64_t sum = 0;
pthread_t t1, t2;
Args args1 { &sum, count };
pthread_create(&t1, NULL, &f1, &args1);
Args args2 { &sum, count };
pthread_create(&t2, NULL, &f1, &args2);
pthread_join(t1, NULL);
pthread_join(t2, NULL);
return sum;
}
uint64_t sum3() {
constexpr uint64_t count = 1'000'000;
uint64_t sum[2] = {0};
pthread_t t1, t2;
Args args1 { &sum[0], count };
pthread_create(&t1, NULL, &f1, &args1);
Args args2 { &sum[1], count };
pthread_create(&t2, NULL, &f1, &args2);
pthread_join(t1, NULL);
pthread_join(t2, NULL);
return sum[0] + sum[1];
}
uint64_t sum4() {
constexpr uint64_t count = 1'000'000;
uint64_t sum[9] = {0};
pthread_t t1, t2;
Args args1 { &sum[0], count };
pthread_create(&t1, NULL, &f1, &args1);
Args args2 { &sum[8], count };
pthread_create(&t2, NULL, &f1, &args2);
pthread_join(t1, NULL);
pthread_join(t2, NULL);
return sum[0] + sum[8];
}
uint64_t sum5() {
constexpr uint64_t count = 1'000'000;
uint64_t sum = 0;
pthread_t t1, t2;
Args args1 { &sum, count };
pthread_create(&t1, NULL, &f2, &args1);
Args args2 { &sum, count };
pthread_create(&t2, NULL, &f2, &args2);
pthread_join(t1, NULL);
pthread_join(t2, NULL);
return sum;
}
int main() {
auto time0 = high_resolution_clock::now();
uint64_t result = sum1();
// uint64_t result = sum2();
// uint64_t result = sum3();
// uint64_t result = sum4();
// uint64_t result = sum5();
auto time1 = high_resolution_clock::now();
auto dt = duration_cast<microseconds>(time1 - time0);
cout << "elapsed: " << dt.count() << " microsec\n";
cout << "result: " << result << '\n';
}