I got two member functions for a class, say foo1 and foo2.
foo1 receives a string label and a data as inputs and calls foo2.
class MyClass {
public:
void foo1(int data, std::string label) {
// do stuff
foo2();
}
void foo2(void) {}
};
Now, I want to be able to create threads for parallel executions of foo1, but only threads of different labels can execute in parallel.
If a thread of labelA is called and another thread of the same label is still running, the first thread has to wait for the second thread to end its execution.
// t1 and t2 should run in parallel, t3 should wait for t1 to end
std::thread t1(foo1, "LabelA", 5);
std::thread t2(foo1, "LabelB", 8);
std::thread t3(foo1, "LabelA", 1);
Is this a known concurrency problem? I coudn't find a way to approach this problem, as it seems that a mutex is not enough in this case.
In summary, my question is: how to allow only certain "types of threads" to execute in parallel?
A mutex is exactly what you want. You just need 1 mutex per label, for instance in a std::map keyed by label. Then, foo1() can lock the std::mutex of the specified label, and unlock it when finished, eg:
std::map<std::string, std::mutex> locks;
class MyClass {
public:
void foo1(int data, std::string label)
{
std::lock_guard<std::mutex> g(locks[label]);
// do stuff
foo2();
}
void foo2()
{
...
}
};
// only one these "LabelA" threads should run in parallel with "LabelB" thread,
// the other "LabelA" thread should wait for the earlier "LabelA" thread to end
locks["LabelA"];
locks["LabelB"];
std::thread t1(&MyClass::foo1, &SomeMyClassObj, 5, "LabelA");
std::thread t2(&MyClass::foo1, &SomeMyClassObj, 8, "LabelB");
std::thread t3(&MyClass::foo1, &SomeMyClassObj, 1, "LabelA");
...
Demo
Related
two threads are created if i use the following:
void func()
{}
std::thread td1;//thread object created.
...
...
//defer the running of td1 until now
td1 = std::thread(func);//temp thread object(rvalue) created
Is there a way to achieve the defer execution but without creating two threads?
I'm not sure what the point is, but...
No operator=, though two threads are constructed:
std::thread td1;
...
std::thread(func).swap(td1);
Or no operator= and only one thread constructed:
std::promise<void> p;
std::thread td1([&]() {
p.get_future().wait();
func();
});
...
p.set_value();
td1.join(); // Can't let p go out of scope pending the thread.
Maybe what you really want is:
std::unique_ptr<std::thread> td1;
...
td1.reset(new std::thread(func));
std::thread td1;
That creates a thread object, but it does not create a thread. So:
std::thread td1;
td1 = std::thread(func);
is perfectly fine code even if you are concerned about performance.
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 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.
class Class {
public:
Class ();
private:
std::thread* updationThread;
};
Constructor:
Class::Class() {
updationThread = new std::thread(&someFunc);
}
At some point in my application, I have to pause that thread and call a function and after execution of that function I have to resume the thread. Let's say it happens here:
void Class::aFunction() {
functionToBeCalled(); //Before this, the thread should be paused
//Now, the thread should be resumed.
}
I have tried to use another thread with function functionToBeCalled() and use thread::join but was unable to do that for some reason.
How can I pause a thread or how can I use thread::join to pause a thread until the other finishes?
I don't think you can easily (in a standard way) "pause" some thread, and then resumes it. I imagine you can send SIGSTOP and SIGCONT if you are using some Unix-flavored OS, but otherwise, you should properly mark the atomic parts inside someFunc() with mutexes and locks, an wraps functionToBeCalled() with a lock on the corresponding mutex:
std::mutex m; // Global mutex, you should find a better place to put it
// (possibly in your object)
and inside the function:
void someFunc() {
// I am just making up stuff here
while(...) {
func1();
{
std::lock_guard<std::mutex> lock(m); // lock the mutex
...; // Stuff that must not run with functionToBeCalled()
} // Mutex unlocked here, by end of scope
}
}
and when calling functionToBeCalled():
void Class::aFunction() {
std::lock_guard<std::mutex> lock(m); // lock the mutex
functionToBeCalled();
} // Mutex unlocked here, by end of scope
You can use a condition variable. An example similar to your situation is given there:
http://en.cppreference.com/w/cpp/thread/condition_variable
I have a class that is used by 2 threads at the same time: one thread adds results (one by one) to the results of a task, the second thread works on those results that are already there.
// all members are copy-able
struct task {
command cmd;
vector<result> results;
};
class generator {
public:
generator(executor* e); // store the ptr
void run();
...
};
class executor {
public:
void run();
void add_result(int command_id, result r);
task& find_task(int command_id);
...
private:
vector<task> tasks_;
condition_variable_any update_condition_;
};
Launch
// In main, we have instances of generator and executor,
// we launch 2 threads and wait for them.
std::thread gen_th( std::bind( &generator::run, gen_instance_) );
std::thread exe_th( std::bind( &executor::run, exe_instance_) );
Generator Thread
void generator::run() {
while(is_running) {
sleep_for_random_seconds();
executor_->add_result( SOME_ID, new_result() );
}
}
Executor thread
void executor::add_result( int command_id, result r ) {
std::unique_lock<std::recursive_mutex> l(mutex_);
task& t = this->find_task(command_id);
t.results.push_back(r);
update_condition_.notify_all();
}
void executor::run() {
while(is_running) {
update_condition_.wait(...);
task& t = this->find_task(SOME_ID);
for(result r: t.results) {
// no live updates are visible here
}
}
}
Generator thread adds a result every few seconds.
Executor thread is an executor itself. It is run via the run method, which waits for an update and when that happens, it works on the results.
Few things to take notice of:
vector of tasks may be big; the results are never disposed;
the for-each loop in executor fetches the task it's working on, then iterates over results, checks which of them are new and processes them. Once processed, they are marked and won't be processed again. This processing may take some time.
The problem occurs when Executor Thread doesn't finish the for loop before another result is added - the result object is not visible in the for loop. Since Executor Thread is working, it doesn't notice the update condition update, doesn't refresh the vector etc. When it finishes (working on a alread-not-actual view of tasks_) it hangs again on the update_condition_.. which was just triggered.
I need to make the code aware, that it should run the loop again after finishing it or make changes to a task visible in the for-each loop. What is the best solution to this problem?
You just need to check whether your vector is empty or not before blocking on the CV. Something like that:
while (running) {
std::unique_lock<std::mutex> lock(mutex);
while (tasks_.empty()) // <-- this is important
update_condition_.wait(lock);
// handle tasks_
}
If your architecture allows it (ie. if you don't need to hold the lock while handling the tasks), you may also want to unlock the mutex ASAP, before handling the tasks so that the producer can push more tasks without blocking. Maybe swapping your tasks_ vector with a temporary one, then unlock the mutex, and only then start handling the tasks in the temporary vector:
while (running) {
std::unique_lock<std::mutex> lock(mutex);
while (tasks_.empty())
update_condition_.wait(lock);
std::vector<task> localTasks;
localTasks.swap(tasks_);
lock.unlock(); // <-- release the lock early
// handle localTasks
}
Edit: ah now I realize this doesn't really fit your situation, because your messages are not directly in tasks_ but in tasks_.results. You get my general idea though, but using it will require structure changes in your code (eg. flatten your tasks / results and always have a cmd associated with a single result).
I act in the following way in the same situation
std::vector< ... > temp;
mutex.lock();
temp.swap( results );
mutex.unlock();
for(result r: temp ){
...
}
A little overhead takes a place, but in general whole code is more readeble and if an amount of calculations is big, then the time for copying goes to zero (sorry for english - it's not native to me)))