I am learning the new multi-threading techniques in C++11. Almost all the tutorials I read on the web is teaching how to launch a new thread(or several threads) executing a function, how to join (or detach) the thread(or threads) later and how to avoid racing conditions using mutex, etc.
But I don't see any of them showing how to make a thread execute several functions at different parts of the program. The question is, with C++11 threads, is it possible to achieve the following? If so, how? (Giving an example will be great).
void func1(std::vector<int> & data1){ ... }
void func2(std::vector<int> & data2){ ... }
// main function version I
int main(){
std::vector<int> data1;
// prepare data1 for func1;
std::thread t1(func1, std::ref(data1));
std::vector<int> data2;
// prepare data2 for func2;
if (func1 in t1 is done){
t1(func2, std::ref(data2));
}
t1.join();
return 0;
}
And further, what if I want to put the the above main function body into a loop, as following. Is it possible? If so, how?
//main function version II
int main(){
std::vector<int> bigdata1;
std::vector<int> bigdata2;
std::thread t1; // Can I do this without telling t1 the function
// to be executed?
for(int i=0; i<10; ++i){
// main thread prepare small chunk smalldata1 from bigdata1 for func1;
if(t1 is ready to execute a function){t1(func1, std::ref(smalldata1));}
// main thread do other stuff, and prepare small chunk smalldata2 from bigdata2 for func2;
if (func1 in t1 is done){
t1(func2, std::ref(smalldata2));
}
}
t1.join();
return 0;
}
Reference from cplusplus.com:
default constructor constructs a thread object that does not represent any thread of execution.
Therefore std::thread t simply doesn't define an executable thread. A thread function has to be provided when creating the thread and it cannot be set afterwards.
For your main function version I, you will have to create two threads. Something as the following:
int main(){
std::vector<int> data1;
// prepare data1 for func1;
std::thread t1(func1, std::ref(data1));
std::vector<int> data2;
// prepare data2 for func2;
t1.join(); // this is how you wait till func1 is done
// you will have to create a new thread here for func2
std::thread t2(func2, std::ref(data2));
t2.join(); // wait for thread2 (func2) to end
return 0;
}
Similarly, you can put them in a loop and it is alright which will give you main function version II.
C++11 threading are primitives intended to allow you to write real libraries. They are not easy to use. You should wrap them.
Something like:
struct tasks {
std::mutex m;
std::condition_variable v;
std::vector<std::packaged_task<void>> work;
std::vector<std::future<void>> finished;
void operator()(){
while(true){
std::packaged_task<void> f;
{
std::unique_lock<std::mutex> l(m);
if (work.empty()){
v.wait(l,[&]{return !work.empty();});
}
f = std::move(work.front());
work.pop_front();
}
if (!f.valid()) return;
f();
}
}
std::future<void> do(std::function<void()> f){
std::packaged_task<void> p(f);
auto r=p.get_future();
{
std::unique_lock<std::mutex> l(m);
work.push_back(std::move(p));
v.notify_one();
}
return r;
}
void start(){
finished.push_back(std::async(std::launch_policy::async,
std::ref(*this)));
}
~tasks(){
std::unique_lock<std::mutex> l(m);
for(auto&&unused:finished){
work.push_back({});
}
v.notify_all();
}
};
use looks like:
int main(){
tasks t;
t.start();
t.do([]({std::cout<<"hello ";});
t.do([]({std::cout<<"world\n";});
}
if you want to know when a task is done, check the future do returns.
Written on phone, not compiled, probably full of typos and errors, but a place to start.
Does not support abort early. Easy to write abaondon which empties work.
Supports multiple consumers (workwe threads) I suspect. On compliant system, at dtor will wait for all threads to finish the queued jobs. Not on MSVC2013 tho.
Related
Basically I am trying to run 2 pieces of code concurrently without freezing eachother, and one of the requires some delay.
so, initial code looks like this:
int main() {
cout << "Hello World!";
std::this_thread::sleep_for(std::chrono::milliseconds(166)); // this freezes the whole program for 166 ms
// do other things
}
i have figured a way with threads:
void ThreadFunction() {
cout << "Hello World!";
std::this_thread::sleep_for(std::chrono::milliseconds(166));
}
int main() {
std::thread t1(ThreadFunction);
t1.detach();
// do other things while also doing what the thread t1 does without waiting 166ms
}
This is not exactly my code, but i am trying to recreate code that works as an example.
Threads work fine, but i hear people saying thread.detach() is not good.
So what are the alternatives?
Your second example seems to be what you want. If you do not want to detach the thread, then don't do it. However, then you must join it and you can only join a thread when it finishes its work at some point.
For this simple example I suggest the following (otherwise you need a condition variable or similar to signal the thread that it should stop):
void ThreadFunction() {
for (int i=0; i <100; ++i) {
cout << "Hello World!";
std::this_thread::sleep_for(std::chrono::milliseconds(166));
}
}
int main() {
std::thread t1(ThreadFunction);
// do other things while also doing what the thread t1 does without waiting 166ms
t1.join(); // blocks until ThreadFunction returns
}
For C++20 you can also use std::jthread
The difference to std::thread is that it will auto join on destruction, thus the code reduces to:
int main() {
std::jthread t1(ThreadFunction);
// do other things while also doing what the thread t1 does without waiting 166ms
// t1.join() will be called automatically when the current scope exits
}
I have a function that must not be called from more than one thread at the same time. Can you suggest some elegant assert for this?
You can use a thin RAII wrapper around std::atomic<>:
namespace {
std::atomic<int> access_counter;
struct access_checker {
access_checker() { check = ++access_counter; }
access_checker( const access_checker & ) = delete;
~access_checker() { --access_counter; }
int check;
};
}
void foobar()
{
access_checker checker;
// assert than checker.check == 1 and react accordingly
...
}
it is simplified version for single use to show the idea and can be improved to use for multiple functions if necessary
Sounds like you need a mutex. Assuming you are using std::thread you can look at the coding example in the following link for specifically using std::mutex: http://www.cplusplus.com/reference/mutex/mutex/
// mutex example
#include <iostream> // std::cout
#include <thread> // std::thread
#include <mutex> // std::mutex
std::mutex mtx; // mutex for critical section
void print_block (int n, char c) {
// critical section (exclusive access to std::cout signaled by locking mtx):
mtx.lock();
for (int i=0; i<n; ++i) { std::cout << c; }
std::cout << '\n';
mtx.unlock();
}
int main ()
{
std::thread th1 (print_block,50,'*');
std::thread th2 (print_block,50,'$');
th1.join();
th2.join();
return 0;
}
In the above code print_block locks mtx, does what it needs to do, and then unlocks mtx. If print_block is called from two different threads, one thread will lock mtx first and the other thread will block on mtx.lock() and be force to wait until the other thread calls mtx.unlock(). This means only one thread can execute the code between mtx.lock() and mtx.unlock() (exclusive) at the same time.
This assumes by "at the same time" you mean at the same literal time. If you only want one thread to be able to call a function I would recommend looking into std::this_thread::get_id which will get you the id of the current thread. An assert could be as simple as storing the owning thread in owning_thread_id and then calling assert(owning_thread_id == std::this_thread::get_id()).
So I have this class:
class foo {
public:
foo() { };
void me1() const {
while(1) {
std::lock_guard<std::mutex> ldock(m);
std::cout << 0;
}
}
void me2() const {
while(1) {
std::lock_guard<std::mutex> ldock(m);
std::cout << 1;
}
}
private:
std::mutex m;
};
Now I want to run this two methods in some two different threads, I do it like this:
int main() {
foo myfoo;
std::thread firstThread(&foo::me1, &myfoo);
std::thread secondThread(&foo::me2, &myfoo);
firstThread.detach();
secondThread.detach();
//while(1) { }
return 0;
}
I don't want to wait for any of this two methods to finish, they will simultaneously run until the main thread will be killed.
Is it ok to have some kind of infinite-loop at the end of main thread? (like the commented while(1) {}).
Or should I call some kinda sleep function?
You need to define an exit condition in your foo::me1() and foo::me2() . If you don't know how to do that, that
sleep(/*number of seconds you want your program to run*/ );
will do just fine.
If you define a termination clause then the bruteforce would be
to expose something like an atomic:
class foo {
public:
std::atomic<int> me1done = false;
std::atomic<int> me2done = false;
foo() { };
void me1() {
while(/* need exit condition here*/) {
std::lock_guard<std::mutex> ldock(m);
std::cout << 0;
}
me1done = true;
}
void me2() {
while(/*need exit condition here*/) {
std::lock_guard<std::mutex> ldock(m);
std::cout << 1;
}
me2done = true;
}
private:
std::mutex m;
};
and then you can check in main by polling every x-seconds.
int main(void)
{
// start your threads and detach
foo myfoo;
std::thread firstThread(&foo::me1, &myfoo);
std::thread secondThread(&foo::me2, &myfoo);
firstThread.detach();
secondThread.detach();
while( not (myfoo.me1done and myfoo.me2done ) )
{
sleep( /* some time */);
}
return 0;
}
If you want to be more elaborate you will have to work with condition variables.
If you want to determine if the two threads have finished your best bet is actually not to detach() the threads but rather join() them before exiting the main thread. That is, you'd kick off both threads and they'll run concurrently and once kicked off you simply join() each. Of course, that assumes that the threads would terminate.
Having a detach()ed thread effectively means you can never be sure if it has finished. That is generally rarely useful and I consider it a mistake that detach() was added to std::thread. However, even with detach()ed thread you can recognize when an objective is achieved without a busy wait. To that end you'd set up suitable variables indicating completion or progress and have them protected by a std::mutex. The main thread would then wait() on a std::condition_variable which gets notify_once()ed by the respective thread upon the completion/progress update which would be done in reasonable intervals. Once all threads have indicated that they are done or have achieved a suitable objective the main() thread can finish.
Using a timer alone is generally not a good approach. The signalling between threads is typically preferable and tends to create a more responsive system. You can still used a timed version of wait() (i.e., wait_until() or wait_for()), e.g., to alert upon suspecting a somehow hung or timed-out thread.
empty infinite loops as while(1) { } are UB.
adding a sleep inside is OK though.
To run infinitely foo::me1/foo::me2, you have several other choices:
int main()
{
foo myfoo;
std::thread firstThread(&foo::me1, &myfoo);
std::thread secondThread(&foo::me2, &myfoo);
firstThread.join(); // wait infinitely as it never ends.
secondThread.join(); // and so never reach
}
or simply use main thread to do one work:
int main()
{
foo myfoo;
std::thread firstThread(&foo::me1, &myfoo);
myfoo.me2(); // work infinitely as it never ends.
firstThread.join(); // and so never reach
}
I have a cycle in C++11 like that:
while (true)
{
std::thread t0(some_work, 0);
...
std::thread tn(some_work, n);
t0.join();
...
tn.join();
}
but creating new threads in every iteration isn't good of course. In C it's easy to use messages to tell threads to wait another iteration, but I want to do it with C++11 tools. I looked at condition_variable, but it isn't solution I think. What can I do with it?
Use Boost to get through!
Note: I do not have C++11, so the code I will show you is for C++98 with Boost libraries. Most of Boost stuff ends up in std::tr1 and subsequently later versions of the standard, so most of this is probably transferrable without boost.
It sounds like you have multiple threads that you are constantly, but not consistently, assigning work to do. The work doesn't always need performing (otherwise your thread could do it in its own loop) or perhaps the thread doesn't have the information to perform it. If this is the case, consider boost::asio::io_service.
With this, you will need to create a thread that is always running, so you'll probably want to put your threads in a class (although you don't need to).
class WorkerThread
{
WorkerThread()
: thread(&WorkerThread::HandleWorkThread, this), io_service(), runThread(true)
{
}
~WorkerThread()
{
// Inform the thread not to run anymore:
runThread = false;
// Wait for the thread to finish:
thread.join();
}
void AssignWork(boost::function<void()> workFunc) { io_service.post(workFunc); }
private:
void HandleWorkThread()
{
while (runThread)
{
// handle work:
io_service.run();
// prepare for more work:
io_service.reset();
}
}
boost::thread thread;
boost::asio::io_service io_service;
bool runThread; // NB: this should be atomic
};
Now you can have the following:
void CalculateThings(int, int);
void CalculateThingsComplex(int, int, double);
// Create two threads. The threads will continue to run and wait for work to do
WorkerThread thread1, thread2;
while (true)
{
thread1.AssignWork(boost::bind(&CalculateThings, 20, 30));
thread2.AssignWork(boost::bind(&CalculateThingsComplex, 2, 5, 3.14));
}
You can continue to assign as much work as necessary. Once the WorkerThreads go out of scope, they will stop running and close nicely
IS there a way of running a function back on the main thread ?
So if I called a function via Async that downloaded a file and then parsed the data. It would then call a callback function which would run on my main UI thread and update the UI ?
I know threads are equal in the default C++ implementation so would I have to create a shared pointer to my main thread. How would I do this and pass the Async function not only the shared pointer to the main thread but also a pointer to the function I want to rrun on it and then run it on that main thread ?
I have been reading C++ Concurrency in Action and chapter four (AKA "The Chapter I Just Finished") describes a solution.
The Short Version
Have a shared std::deque<std::packaged_task<void()>> (or a similar sort of message/task queue). Your std::async-launched functions can push tasks to the queue, and your GUI thread can process them during its loop.
There Isn't Really a Long Version, but Here Is an Example
Shared Data
std::deque<std::packaged_task<void()>> tasks;
std::mutex tasks_mutex;
std::atomic<bool> gui_running;
The std::async Function
void one_off()
{
std::packaged_task<void()> task(FUNCTION TO RUN ON GUI THREAD); //!!
std::future<void> result = task.get_future();
{
std::lock_guard<std::mutex> lock(tasks_mutex);
tasks.push_back(std::move(task));
}
// wait on result
result.get();
}
The GUI Thread
void gui_thread()
{
while (gui_running) {
// process messages
{
std::unique_lock<std::mutex> lock(tasks_mutex);
while (!tasks.empty()) {
auto task(std::move(tasks.front()));
tasks.pop_front();
// unlock during the task
lock.unlock();
task();
lock.lock();
}
}
// "do gui work"
std::this_thread::sleep_for(std::chrono::milliseconds(1000));
}
}
Notes:
I am (always) learning, so there is a decent chance that my code is not great. The concept is at least sound though.
The destructor of the return value from std::async (a std::future<>) will block until the operation launched with std::async completes (see std::async ), so waiting on the result of a task (as I do in my example) in one_off might not be a brilliant idea.
You may want to (I would, at least) create your own threadsafe MessageQueue type to improve code readability/maintainability/blah blah blah.
I swear there was one more thing I wanted to point out, but it escapes me right now.
Full Example
#include <atomic>
#include <chrono>
#include <deque>
#include <iostream>
#include <mutex>
#include <future>
#include <thread>
// shared stuff:
std::deque<std::packaged_task<void()>> tasks;
std::mutex tasks_mutex;
std::atomic<bool> gui_running;
void message()
{
std::cout << std::this_thread::get_id() << std::endl;
}
void one_off()
{
std::packaged_task<void()> task(message);
std::future<void> result = task.get_future();
{
std::lock_guard<std::mutex> lock(tasks_mutex);
tasks.push_back(std::move(task));
}
// wait on result
result.get();
}
void gui_thread()
{
std::cout << "gui thread: "; message();
while (gui_running) {
// process messages
{
std::unique_lock<std::mutex> lock(tasks_mutex);
while (!tasks.empty()) {
auto task(std::move(tasks.front()));
tasks.pop_front();
// unlock during the task
lock.unlock();
task();
lock.lock();
}
}
// "do gui work"
std::this_thread::sleep_for(std::chrono::milliseconds(1000));
}
}
int main()
{
gui_running = true;
std::cout << "main thread: "; message();
std::thread gt(gui_thread);
for (unsigned i = 0; i < 5; ++i) {
// note:
// these will be launched sequentially because result's
// destructor will block until one_off completes
auto result = std::async(std::launch::async, one_off);
// maybe do something with result if it is not void
}
// the for loop will not complete until all the tasks have been
// processed by gui_thread
// ...
// cleanup
gui_running = false;
gt.join();
}
Dat Output
$ ./messages
main thread: 140299226687296
gui thread: 140299210073856
140299210073856
140299210073856
140299210073856
140299210073856
140299210073856
Are you looking for std::launch::deferred ? Passing this parameter to std::async makes the task executed on the calling thread when the get() function is called for the first time.