Функтор, защищенный std::mutex с помощью оболочки
struct foo
{
void operator()(int count, std::mutex& guard)
{
for (int i = 0; i < count + 1; ++i)
{
guard.lock();
std::cout << i << '\t' << std::this_thread::get_id() << '\n';
guard.unlock();
}
}
};
struct wruper_foo
{
void operator()(int count)
{
f(count, guard);
}
private:
std::mutex guard;
foo f;
};
int main()
{
std::vector<std::thread> thrs;
wruper_foo functor;
for (int i = 0; i < 3; ++i)
{
thrs.push_back(std::move(std::thread(functor, i)));
}
for (auto& thr : thrs)
{
if (thr.joinable())
thr.join();
}
}
код выдает ошибку: std::tuple<wruper_foo,int>::tuple: нет перегруженной функции, принимающей 2 аргументов
Прошу помощи разобраться, что я делаю не так?
Ответы (2 шт):
Автор решения: Damir Hakimof
→ Ссылка
#include <iostream>
#include <mutex>
#include <thread>
#include <vector>
struct foo {
void operator()(int count, std::mutex& guard) {
for (int i = 0; i < count + 1; ++i) {
std::lock_guard<std::mutex> lock(guard);
std::cout << i << '\t' << std::this_thread::get_id() << '\n';
}
}
};
struct wruper_foo {
void operator()(int count) {
f(count, guard);
}
private:
std::mutex guard;
foo f;
};
int main() {
std::vector<std::thread> thrs;
thrs.reserve(3);
wruper_foo functor;
for (int i = 0; i < 3; ++i) {
thrs.emplace_back(std::ref(functor), i);
}
for (auto& thr : thrs) {
if (thr.joinable()) {
thr.join();
}
}
}
Автор решения: user7860670
→ Ссылка
Более лаконичный вариант без создания дополнительных классов, держащих состояние, но с использованием jthread, который в RAII стиле автоматически ожидает завершения потока в деструкторе. Важно, что вектор уничтожается строго до мьютекса, который используют потоки. А ручные вызовы lock unlock заменены RAII объектом.
#include <iostream>
#include <functional>
#include <mutex>
#include <thread>
#include <vector>
void foo(int const count, ::std::reference_wrapper<::std::mutex> const mutex_ref)
{
for (int i{}; i < count + 1; ++i)
{
::std::lock_guard const lock{mutex_ref.get()};
::std::cout << i << '\t' << ::std::this_thread::get_id() << '\n';
}
}
int main()
{
::std::mutex mutex{};
::std::vector<::std::jthread> thrs{};
thrs.reserve(3);
for (int i{}; i < 3; ++i)
{
thrs.emplace_back(::foo, i, ::std::reference_wrapper{mutex});
}
return 0;
}