Reputation: 723
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?
Upvotes: 2
Views: 8521
Reputation: 217275
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
}
Upvotes: 1
Reputation: 153830
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.
Upvotes: 2
Reputation: 3125
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.
Upvotes: 3