Last active
April 23, 2021 02:14
-
-
Save cleoold/67f37dbd1d1b2421b4ae5067c39e9f6d to your computer and use it in GitHub Desktop.
raii safe c++ thread
This file contains 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
#pragma once | |
// source: Scott Meyers - Effective Modern C++-O'Reilly item 37 | |
// compile flag: -lpthread -Wall -std=c++20 | |
#include <thread> | |
#include <type_traits> | |
// RAII managed thread class | |
class thread_raii { | |
public: | |
enum class dtor_action { | |
join, detach | |
}; | |
explicit thread_raii(dtor_action action_, std::thread &&thread_) noexcept | |
: action{action_}, thread{std::move(thread_)} | |
{} | |
template<class Fn, class ...Args | |
#ifdef __cpp_concepts | |
> requires std::is_invocable_v<Fn, Args...> | |
#else | |
, std::enable_if_t<std::is_invocable_v<Fn, Args...>, int> = 0> | |
#endif | |
explicit thread_raii(dtor_action action_, Fn &&f, Args &&...args) | |
: thread_raii{action_, std::thread{std::forward<Fn>(f), std::forward<Args>(args)...}} | |
{} | |
thread_raii(thread_raii &&) noexcept = default; | |
thread_raii &operator=(thread_raii &&o) noexcept { | |
std::swap(action, o.action); | |
std::swap(thread, o.thread); | |
return *this; | |
}; | |
// either join or detach when destructed to avoid program termination | |
~thread_raii() { | |
if (thread.joinable()) { | |
switch (action) { | |
case dtor_action::join: | |
thread.join(); // noexcept? | |
break; | |
case dtor_action::detach: | |
default: | |
thread.detach(); | |
break; | |
} | |
} | |
} | |
auto &get() noexcept { | |
return thread; | |
} | |
private: | |
dtor_action action; | |
std::thread thread; // thread is constructed last to ensure it can use | |
// proper states | |
}; |
This file contains 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 <iostream> | |
#include <vector> | |
#include "thread_raii.hpp" | |
int main() { | |
auto ths = std::vector<thread_raii>{}; | |
for (auto i = 0; i < 5; ++i) { | |
ths.emplace_back(thread_raii::dtor_action::join, [](auto x) { | |
auto s = std::to_string(x) + '\n'; | |
std::cout << s; | |
}, i); | |
} | |
auto thz = std::move(ths); | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment