std::thread with static function
#include
void called_from_static_fn( const std::string& arg )
{
// ...
}
std::thread t1(called_from_static_fn, "static");
// ...
t1.join();
std::thread with member fn
class Foo
{
public:
void Bar( const string& arg)
{
// ...
}
};
Foo foo;
thread t1(&Foo::Bar, &foo, "member");
// ...
t1.join();
std::thread with lambda
int ret = 0;
thread t( [ &ret ](int m, int n) { ret = m + n; }, 2, 4 );
t.join();
std::thread in array
static int twice(int m) { return 2 * m; }
vector< thread > threads;
for (int i = 0; i < 10; ++i)
{
threads.push_back( thread(twice, i));
}
for (auto& t : threads)
{
t.join();
}
catch exception in a thread
static int DoNotTryAtHome()
{
throw exception("I said NO");
}
thread t1(DoNotTryAtHomeNoThrow);
t1.join();
use mutex on shared variable
class Foo
{
int m_Bar = 0;
mutex m_LockBar;
public:
void AddBarSafe(int add)
{
lock_guard< mutex > guard(m_LockBar);
int temp = m_Bar;
this_thread::sleep_for(chrono::milliseconds(10));
m_Bar = temp + add;
}
};
{
Foo foo;
vector ts;
ts.emplace_back(thread{ &Foo::AddBarSafe, &foo, 2 });
ts.emplace_back(thread{ &Foo::AddBarSafe, &foo, 3 });
ts.emplace_back(thread{ &Foo::AddBarSafe, &foo, 4 });
for (auto& t : ts) { t.join(); }
}
std::thread on class operator()
struct funcCount
{
int &i;
funcCount(int& i_) : i(i_) {}
void operator()()
{
for (unsigned j = 0; j < 1000; ++j)
{
++i;
this_thread::sleep_for(chrono::milliseconds(1));
}
}
};
{
int some_local_state = 0;
funcCount my_func(some_local_state);
std::thread my_thread(my_func);
// my_thread.detach(); // undefined behaviour
my_thread.join();
}
thread_guard
class thread_guard
{
std::thread& t;
public:
explicit thread_guard(std::thread& t_) : t(t_) {}
~thread_guard()
{
if (t.joinable()) t.join();
}
thread_guard(thread_guard const&) = delete;
thread_guard operator = (thread_guard const &) = delete;
};
void do_something_stupid()
{
for (int i = 1; i < 10; ++i)
{
if (i % 5 == 0)
{
throw std::exception("ooops");
}
}
}
{
int some_local_state = 0;
try
{
funcCount my_func(some_local_state);
std::thread t(my_func);
thread_guard g(t);
do_something_stupid();
}
catch (...)
{
}
}
move around thread
{
std::thread t1(called_from_static_fn, "static");
std::thread t2 = std::move(t1);
t1 = std::thread(&TestMultiThread::called_from_member_fn, this, "static");
std::thread t3;
t3 = std::move(t2);
// t1 = std::move(t3); // terminate
t1.join();
t3.join();
}
async
{
future result(async(called_from_static_fn, "static"));
result.get();
}
{
Foo foo;
future result(async(&Foo::Bar, &foo, "member"));
result.get();
}
{
future result(async([](int m, int n) { return m + n; }, 2, 4));
int ret = result.get();
}
{
vector< future< int > > futures;
for (int i = 0; i < 10; ++i)
{
futures.push_back(async(twice, i));
}
for (auto& e : futures)
{
cout << e.get() << endl;
}
}
async will throw exception at convenient time
{
future result(async(DoNotTryAtHome));
try
{
int ret = result.get();
}
catch (exception& ex)
{
printf("exception caught : %s", ex.what());
}
}
wait for future
{
future f = async( [](){ cout << "bar" << endl; } );
if (f.wait_for(chrono::milliseconds(0)) == future_status::deferred)
{
cout << "foo and wait for bar" << endl;
f.get();
}
else
{
while (f.wait_for(chrono::milliseconds(10)) != future_status::ready)
{
cout << "foo waiting ... " << endl;
}
cout << "foo" << endl;
}
}
condition_variable
{
mutex m_LockReadyProcess;
condition_variable m_Condition;
string m_Log;
bool m_Ready = false;
bool m_Processed = false;
}
void worker_thread()
{
unique_lock lock(m_LockReadyProcess);
m_Condition.wait(lock, [=]{return m_Ready; });
cout << "Worker thread is processing data\n";
m_Log += " after processing";
m_Processed = true;
cout << "Worker thread signals data processing completed\n";
lock.unlock();
m_Condition.notify_one();
}
{
thread worker( &TestMultiThread::worker_thread, this);
m_Log = "Example data";
{
lock_guard guard(m_LockReadyProcess);
m_Ready = true;
cout << "main() signals data ready for processing\n";
}
m_Condition.notify_one();
{
unique_lock lock(m_LockReadyProcess);
m_Condition.wait(lock, [=]{return m_Processed; });
}
cout << "Back in main(), data = " << m_Log << '\n';
worker.join();
}
No comments:
Post a Comment