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
}
Related
I am a beginner to c++, so I don't know much
here is a function
void example(){
for(int i=0; i<5; i++){
// do stuff
}
}
if I call this function, it will wait for it to be finished before continuing
int main(){
example();
otherThingsGoHere();
otherThingsGoHere();
otherThingsGoHere();
return 0;
}
the otherThingsGoHere() doesn't get called until example() is done
my goal is to have that function be able to loop 60/70 fps in a loop forever
and I did get it working, except nothing below that will happen since it is in an infinite loop.
I've been a c# developer for some time and I know that in c#, you can use async functions to run on a seperate thread. How do I impliment something like this in c++?
Edit: I am not asking for you to put the otherThingsGoHere in front of the main because the other things is going to be another loop, so I need both of them to run at the same time
You need to use a std::thread and run the example() function from that new thread.
A std::thread can be started when constructed with a function to run.
It will run potentially in parallel to the main thread running the otherThingsGoHere.
I wrote potentially because it depends on your system and number of cores. If you have a PC with multiple cores it can actually run like that.
Before main() exits it should wait for the other thread to end gracefully, by calling thread::join().
A minimal example for your case would be:
#include <thread>
#include <iostream>
void example() {
for (int i = 0; i<5; i++) {
std::cout << "thread...\n";
std::this_thread::sleep_for(std::chrono::milliseconds(100));
}
}
void otherThingsGoHere() {
std::cout << "do other things ...\n";
std::this_thread::sleep_for(std::chrono::milliseconds(100));
}
int main() {
std::thread t{ example };
otherThingsGoHere();
otherThingsGoHere();
otherThingsGoHere();
t.join();
return 0;
}
Some more info here: Simple example of threading in C++
I've been trying to develop a better understanding of C++ threading, by which I have written the following example:
#include <functional>
#include <iostream>
#include <thread>
class Test {
public:
Test() { x = 5; }
void act() {
std::cout << "1" << std::endl;
std::thread worker(&Test::changex, this);
worker.detach();
std::cout << "2" << std::endl;
}
private:
void changex() {
std::cout << "3" << std::endl;
x = 10;
std::cout << "4" << std::endl;
}
int x;
};
int main() {
Test t;
t.act();
return 0;
}
To me, I should get the following output when compiled with g++ linked with -pthread:
1
2
3
4
as the cout calls are in that order. However, the output is inconsistent. 1 and 2 are always printed in order, but sometimes the 3 and or 4 are either omitted or printed double. i.e. 12, 123, 1234, or 12344
My working theory is that the main thread exits before the worker thread begins working or completes, thus resulting in the omission of output. I can immediately think of a solution to this problem in creating a global boolean variable to signify when the worker thread has completed that the main thread waits on for a state change before exiting. This alleviates the issue.
However, this feels to me like a highly messy approach that likely has a more clean solution, especially for an issue like this that likely comes up often in threading.
Just some general advice, that holds both for using raw pthreads in C++ and for pthreads wrapped in std::thread: The best way to get readable, comprehensible and debuggable behavior is to make thread synchronization and lifetime management explicit. I.e. avoid using pthread_kill, pthread_cancel, and in most cases, avoid detaching threads and instead do explicit join.
One design pattern I like is using an std atomic flag. When main thread wants to quit, it sets the atomic flag to true. The worker threads typically do their work in a loop, and check the atomic flag reasonably often, e.g. once per lap of the loop. When they find main has ordered them to quit, they clean up and return. The main thread then join:s with all workers.
There are some special cases that require extra care, for example when one worker is stuck in a blocking syscall and/or C library function. Usually, the platform provides ways of getting out of such blocking calls without resorting to e.g. pthread_cancel, since thread cancellation works very badly with C++. One example of how to avoid blocking is the Linux manpage for getaddrinfo_a, i.e. asynchronous network address translation.
One additional nice design pattern is when workers are sleeping in e.g. select(). You can then add an extra control pipe between main and the worker. Main signals the worker to quit by send():ing one byte over the pipe, thus waking up the worker if it sleeps in select().
Example of how this could be done:
#include <functional>
#include <iostream>
#include <thread>
class Test {
std::thread worker; // worker is now a member
public:
Test() { x = 5; } // worker deliberately left without a function to run.
~Test()
{
if (worker.joinable()) // worker can be joined (act was called successfully)
{
worker.join(); // wait for worker thread to exit.
// Note destructor cannot complete if thread cannot be exited.
// Some extra brains needed here for production code.
}
}
void act() {
std::cout << "1" << std::endl;
worker = std::thread(&Test::changex, this); // give worker some work
std::cout << "2" << std::endl;
}
// rest unchanged.
private:
void changex() {
std::cout << "3" << std::endl;
x = 10;
std::cout << "4" << std::endl;
}
int x;
};
int main() {
Test t;
t.act();
return 0;
} // test destroyed here. Destruction halts and waits for thread.
Update
I did as recommended to create a std::vector of threads outside the scope, so I can .join() as soon as the thread has finished it's job, the problem now is that as soon as the thread is joined the program not exactly crashes, because it still runs in the background but the abort window appears. I checked if the thread was joinable and indeed it is when trying to join.
Timer.cpp:
void Timer::Start(int time, void(*lf)()) {
slaveTimer = std::thread(&Timer::RunTimer, this, time, lf);
}
void Timer::RunTimer(int seconds, void(*lf)()) {
auto time = (std::chrono::seconds)seconds;
std::this_thread::sleep_for(time);
lf();
slaveTimer.join(); //Program Crashes
}
Main.cpp
Timer timer1(10, [](){ std::cout << "Hello World" << std::endl; });
Original Post
I was trying to make coroutines with multithreading, the thing is that when I try to make the thread wait for X seconds, i then thread.detach(); but that takes a couple of milliseconds and the screen (because I’m displaying with GL) freezes. One of the possible solutions that I can think of is making the thread detach itself before executing the action, but that doesn’t seem possible, so I was wondering if there is any way to do that or something similar to solve this problem.
You cannot call join from the function which is the body of execution thread. It will give you the error:
Reference
Error Conditions :
resource_deadlock_would_occur if this->get_id() ==
std::this_thread::get_id() (deadlock detected)
you need to add additional method for instance
void Timer::stop() {
slaveTimer.join();
}
and call this method from thread which created timer1 instance
Timer timer1(10, [](){ std::cout << "Hello World" << std::endl; });
timer1.stop();
or join thread in dtor of Timer:
Timer::~Timer() {
slaveTimer.join();
}
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 vector of Timer Objects. Each Timer Object launches an std::thread that simulates a growing period. I am using a Command pattern.
What is happening is each Timer is getting executed one after another but what I really want is for one to be executed....then once finished, the next one...once finished the next...while not interfering with the main execution of the program
class Timer
{
public:
bool _bTimerStarted;
bool _bTimerCompleted;
int _timerDuration;
virtual ~Timer() { }
virtual void execute()=0;
virtual void runTimer()=0;
inline void setDuration(int _s) { _timerDuration = _s; };
inline int getDuration() { return _timerDuration; };
inline bool isTimerComplete() { return _bTimerCompleted; };
};
class GrowingTimer : public Timer
{
public:
void execute()
{
//std::cout << "Timer execute..." << std::endl;
_bTimerStarted = false;
_bTimerCompleted = false;
//std::thread t1(&GrowingTimer::runTimer, this); //Launch a thread
//t1.detach();
runTimer();
}
void runTimer()
{
//std::cout << "Timer runTimer..." << std::endl;
_bTimerStarted = true;
auto start = std::chrono::high_resolution_clock::now();
std::this_thread::sleep_until(start + std::chrono::seconds(20));
_bTimerCompleted = true;
std::cout << "Growing Timer Finished..." << std::endl;
}
};
class Timers
{
std::vector<Timer*> _timers;
struct ExecuteTimer
{
void operator()(Timer* _timer) { _timer->execute(); }
};
public:
void add_timer(Timer& _timer) { _timers.push_back(&_timer); }
void execute()
{
//std::for_each(_timers.begin(), _timers.end(), ExecuteTimer());
for (int i=0; i < _timers.size(); i++)
{
Timer* _t = _timers.at(i);
_t->execute();
//while ( ! _t->isTimerComplete())
//{
//}
}
}
};
Executing the above like:
Timers _timer;
GrowingTimer _g, g1;
_g.setDuration(BROCCOLI::growTimeSeconds);
_g1.setDuration(BROCCOLI::growTimeSeconds);
_timer.add_timer(_g);
_timer.add_timer(_g1);
start_timers();
}
void start_timers()
{
_timer.execute();
}
In Timers::execute I am trying a few different ways to execute the first and not execute the
next until I somehow signal it is done.
UPDATE:
I am now doing this to execute everything:
Timers _timer;
GrowingTimer _g, g1;
_g.setDuration(BROCCOLI::growTimeSeconds);
_g1.setDuration(BROCCOLI::growTimeSeconds);
_timer.add_timer(_g);
_timer.add_timer(_g1);
//start_timers();
std::thread t1(&Broccoli::start_timers, this); //Launch a thread
t1.detach();
}
void start_timers()
{
_timer.execute();
}
The first time completes (I see the "completed" cout), but crashes at _t->execute(); inside the for loop with an EXEC_BAD_ACCESS. I added a cout to check the size of the vector and it is 2 so both timers are inside. I do see this in the console:
this Timers * 0xbfffd998
_timers std::__1::vector<Timer *, std::__1::allocator<Timer *> >
if I change the detach() to join() everything completes without the crash, but it blocks execution of my app until those timers finish.
Why are you using threads here? Timers::execute() calls execute on a timer, then waits for it to finish, then calls execute on the next, and so forth. Why don't you just call the timer function directly in Timers::execute() rather than spawning a thread and then waiting for it?
Threads allow you to write code that executes concurrently. What you want is serial execution, so threads are the wrong tool.
Update: In the updated code you run start_timers on a background thread, which is good. However, by detaching that thread you leave the thread running past the end of the scope. This means that the timer objects _g and _g1 and even the Timers object _timers are potentially destroyed before the thread has completed. Given the time-consuming nature of the timers thread, and the fact that you used detach rather than join in order to avoid your code blocking, this is certainly the cause of your problem.
If you run code on a thread then you need to ensure that all objects accessed by that thread have a long-enough lifetime that they are still valid when the thread accesses them. For detached threads this is especially hard to achieve, so detached threads are not recommended.
One option is to create an object containing _timers, _g and _g1 along side the thread t1, and have its destructor join with the thread. All you need to do then is to ensure that the object lives until the point that it is safe to wait for the timers to complete.
If you don't want to interfere with the execution of the program, you could do something like #Joel said but also adding a thread in the Timers class which would execute the threads in the vector.
You could include a unique_ptr to the thread in GrowingTimer instead of creating it as a local object in execute and calling detach. You can still create the thread in execute, but you would do it with a unique_ptr::reset call.
Then use join instead of isTimerComplete (add a join function to the Timer base class). The isTimerComplete polling mechanism will be extremely inefficient because it will basically use up that thread's entire time slice continually polling, whereas join will block until the other thread is complete.
An example of join:
#include <iostream>
#include <chrono>
#include <thread>
using namespace std;
void threadMain()
{
this_thread::sleep_for(chrono::seconds(5));
cout << "Done sleeping\n";
}
int main()
{
thread t(threadMain);
for (int i = 0; i < 10; ++i)
{
cout << i << "\n";
}
t.join();
cout << "Press Enter to exit\n";
cin.get();
return 0;
}
Note how the main thread keeps running while the other thread does its thing. Note that Anthony's answer is right in that it doesn't really seem like you need more than one background thread that just executes tasks sequentially rather than starting a thread and waiting for it to finish before starting a new one.