Skip to content

Instantly share code, notes, and snippets.

@bananu7
Last active September 28, 2021 08:16
Show Gist options
  • Save bananu7/bc59f94b1e861209ddb71e77ba9449bc to your computer and use it in GitHub Desktop.
Save bananu7/bc59f94b1e861209ddb71e77ba9449bc to your computer and use it in GitHub Desktop.
Szkolenie C++ 2021-09-27
#include <thread>
#include <ranges>
#include <mutex>
#include <array>
#include <iostream>
#include <chrono>
#include <map>
#include <format>
#include <random>
using namespace std::chrono_literals;
class Bank {
std::map<int, int> accounts;
mutable std::mutex m;
public:
void add(int acc, int val = 100) {
accounts.insert({ acc, val });
}
void transfer(int a, int b, int value) {
{
std::scoped_lock lock(m);
accounts[b] += value;
//}
std::this_thread::sleep_for(10ms);
//{
//std::scoped_lock lock(m);
accounts[a] -= value;
}
}
int sum() const {
std::scoped_lock lock(m);
int sum = 0;
for (int v : std::views::values(accounts)) {
sum += v;
}
return sum;
}
};
int main() {
Bank bank;
for (int i : std::views::iota(0, 10)) {
bank.add(i);
}
std::jthread sum_worker([&] {
while (true) {
std::this_thread::sleep_for(50ms);
std::cout << std::format("Sum : {}\n", bank.sum());
}
});
std::random_device rd;
std::mt19937 gen(rd());
std::uniform_int_distribution<> acc(0, 10);
std::uniform_int_distribution<> val(30, 60);
auto random_transfer = [&] {
int counter = 100;
while (counter--) {
int a = acc(gen);
int b = acc(gen);
int v = val(gen);
bank.transfer(a, b, v);
std::cout << std::format("Transfer {} -> {} ({})\n", a, b, v);
std::this_thread::sleep_for(50ms);
}
};
std::array<std::jthread, 5> transfer_workers;
for (auto& t : transfer_workers)
t = std::jthread(random_transfer);
}
std::future<int> foo() {
// create promise
// get future from the promise
// move promise to a thread that will fulfill it
}
int main() {
auto f = foo();
std::cout << f.get();
}
#include <iostream>
#include <string>
#include <type_traits>
#include <vector>
#include <algorithm>
#include <map>
#include <stdexcept>
#include <numeric>
#include <random>
#include <thread>
#include <mutex>
#include <chrono>
#include <atomic>
#include <shared_mutex>
#include <vector>
#include <barrier>
#include <latch>
#include <future>
using namespace std::chrono_literals;
std::future<int> foo(std::chrono::seconds delay) {
std::promise<int> promise;
std::future<int> result = promise.get_future();
std::thread t([=, p = std::move(promise)]() mutable {
std::this_thread::sleep_for(delay);
p.set_value_at_thread_exit(1);
});
t.detach();
return result;
}
// packaged_task
// async
int main() {
auto f = foo(3s);
auto g = foo(6s);
std::cout << "Waiting...";
//std::cout << f.get() << g.get();
//std::cout.operator<<(f.get()).operator<<(g.get());
std::cout << std::format("{}{}", f.get(), g.get());
}
#include <iostream>
#include <string>
#include <type_traits>
#include <vector>
#include <algorithm>
#include <map>
#include <stdexcept>
#include <numeric>
#include <random>
#include <thread>
#include <mutex>
#include <chrono>
#include <atomic>
#include <shared_mutex>
#include <vector>
#include <barrier>
#include <latch>
using namespace std::chrono_literals;
int main() {
int x = 0;
int y = 0;
std::jthread yt([&] {
std::this_thread::sleep_for(1s);
x = 1;
});
std::jthread xt([&] {
std::this_thread::sleep_for(1s);
y = 1;
});
std::cout << "Waiting...\n";
std::cout << std::format("x: {}, y: {}\n", x, y);
}
priorytety: https://stackoverflow.com/questions/11666610/how-to-give-priority-to-privileged-thread-in-mutex-locking
ksiazka: https://helion.pl/ksiazki/jezyk-c-i-przetwarzanie-wspolbiezne-w-akcji-wydanie-ii-anthony-williams,jcppw2.htm#format/d
#include <thread>
#include <mutex>
#include <iostream>
#include <array>
#include <chrono>
#include <format>
#include <ranges>
using namespace std::chrono_literals;
int main() {
const int n = 5;
std::array<std::mutex, n> forks;
auto philosopher = [&](int i) {
std::mutex& left = forks[i];
std::mutex& right = forks[(i + 1) % n];
left.lock();
std::this_thread::sleep_for(1s);
right.lock();
std::cout << std::format("Philosopher {} eating\n", i);
left.unlock();
right.unlock();
};
std::array<std::thread, n> philosophers;
for (int i : std::views::iota(0,n)) {
philosophers[i] = std::thread(philosopher, i);
}
}
#include <iostream>
#include <string>
#include <type_traits>
#include <vector>
#include <algorithm>
#include <map>
#include <stdexcept>
#include <numeric>
#include <random>
#include <thread>
#include <mutex>
#include <chrono>
#include <omp.h>
#include <atomic>
#include <shared_mutex>
#include <vector>
#include <barrier>
using namespace std::chrono_literals;
int main() {
std::string s = " ";
std::shared_mutex m;
auto writer = [&] {
while (true) {
{
std::unique_lock lock(m);
for (char& c : s) {
c = 'x';
std::this_thread::sleep_for(50ms);
}
}
std::this_thread::sleep_for(150ms);
{
std::unique_lock lock(m);
for (char& c : s) {
c = ' ';
std::this_thread::sleep_for(50ms);
}
}
std::this_thread::sleep_for(150ms);
}
};
auto reader = [&](int i) {
while (true) {
{
std::shared_lock lock(m);
std::cout << std::format("{} : {}\n", i, s);
}
std::this_thread::sleep_for(50ms);
}
};
std::jthread writerT(writer);
std::jthread readerT(reader, 0);
std::jthread readerT2(reader, 1);
}
#include <iostream>
#include <string>
#include <type_traits>
#include <vector>
#include <algorithm>
#include <map>
#include <stdexcept>
#include <numeric>
#include <random>
#include <thread>
#include <mutex>
#include <chrono>
#include <omp.h>
#include <atomic>
#include <shared_mutex>
#include <vector>
#include <barrier>
using namespace std::chrono_literals;
std::string str = " ";
std::mutex io_mtx;
std::vector<int> v;
std::shared_mutex mtx;
std::barrier sync_point(2, []() noexcept {std::cout << "------------------------------\n"; });
void writer(const char cw, std::chrono::milliseconds pause) {
char x = cw;
while (true) {
{
std::unique_lock<std::shared_mutex> lock(mtx);
x = cw;
for (char& c : str) {
c = x;
std::this_thread::sleep_for(5ms);
}
}
std::this_thread::sleep_for(pause);
{
std::unique_lock<std::shared_mutex> lock(mtx);
x = ' ';
for (char& c : str) {
c = x;
std::this_thread::sleep_for(5ms);
}
}
sync_point.arrive_and_wait();
std::this_thread::sleep_for(pause);
}
}
void reader(int number) {
std::string copy = str;
while (true) {
{
std::shared_lock<std::shared_mutex> lock(mtx);
copy = str;
}
{
std::lock_guard<std::mutex> lock(io_mtx);
std::cout << number << " [" << copy << "]\n";
}
std::this_thread::sleep_for(50ms);
}
}
int main()
{
std::jthread writer_x(writer, 'x', 1000ms);
std::jthread writer_y(writer, 'y', 100ms);
std::jthread readerT(reader, 0);
std::jthread readerT2(reader, 1);
}
#include <iostream>
#include <string>
#include <type_traits>
#include <vector>
#include <algorithm>
#include <map>
#include <stdexcept>
#include <numeric>
#include <random>
#include <thread>
#include <mutex>
#include <chrono>
#include <omp.h>
#include <atomic>
#include <shared_mutex>
#include <vector>
#include <barrier>
#include <condition_variable>
using namespace std::chrono_literals;
int main() {
std::string s = " ";
bool writerWaiting;
std::shared_mutex m;
// reader (low-priority): wait([](w == false)), lock(M), ..., unlock(M)
// writer (high-priority): w=true, lock(M), ..., unlock(M), w=false
std::condition_variable_any cv;
auto writer = [&] {
while (true) {
writerWaiting = true;
{
std::unique_lock lock(m);
for (char& c : s) {
c = 'x';
std::this_thread::sleep_for(50ms);
}
writerWaiting = false;
}
cv.notify_all();
std::this_thread::sleep_for(150ms);
writerWaiting = true;
{
std::unique_lock lock(m);
for (char& c : s) {
c = ' ';
std::this_thread::sleep_for(50ms);
}
writerWaiting = false;
}
cv.notify_all();
std::this_thread::sleep_for(150ms);
}
};
auto reader = [&](int i) {
while (true) {
{
std::shared_lock lock(m);
cv.wait(lock, [&] {return !writerWaiting; });
std::cout << std::format("{} : {}\n", i, s);
std::this_thread::sleep_for(50ms);
}
}
};
std::jthread writerT(writer);
std::jthread readerT(reader, 0);
std::jthread readerT2(reader, 1);
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment