C++ MultiThreading block main thread - c++

I try to make a timeout in a C++ program:
...
void ActThreadRun(TimeOut *tRun)
{
tRun->startRun();
}
...
void otherFunction()
{
TimeOut *tRun = new TimeOut();
std::thread t1 (ActThreadRun, tRun);
t1.join();
while(tRun->isTimeoutRUN())
{
manageCycles();
}
}
...
The timeout is done after 3 seconds, and tRun->isTimeoutRUN() changes its state.
But if I "join" the thread, I block the program, so it waits 3 seconds before continuing, so it never goes into my while loop...
But if I don't "join" the thread, the thread never times out, and tRun->isTimeoutRUN() never changes, so it runs infinitely.
I'm not good with threads, so I'm asking your help because I don't understand the tutorials on this in C++.

You can use the new C++11 facilities
// thread example
#include <iostream> // std::cout
#include <thread> // std::thread
void sleep()
{
std::chrono::milliseconds dura( 2000 );
std::this_thread::sleep_for( dura );//this makes this thread sleep for 2s
}
int main()
{
std::thread timer(sleep);// launches the timer
int a=2;//this dummy instruction can be executed even if the timer thread did not finish
timer.join(); // wait unil timer finishes, ie until the sleep function is done
std::cout<<"Time expired!";
return 0;
}
Hope that helps

Related

Accurate timer based processing implementation using condition variable

I need a thread to perform processing every one second accurately. Suppose if the worker thread is busy on some operation that takes more than one second, I want the worker thread to miss the 1s expiry notification and perform the processing in the next cycle.
I am trying to implement this using two threads. One thread is a worker thread, another thread sleeps for one second and notifies the worker thread via condition variable.
Code is shown below
Worker thread
while(!threadExit){
std::unique_lock<std::mutex> lock(mutex);
// Block until a signal is received
condVar_.wait(lock, [this](){return (threadExit || performProc);)});
if(threadExit_){
break;
}
// Perform the processing
..............
}
Timer thread
while(!threadExit)
{
{
std::unique_lock<std::mutex> lock(mutex);
performProc= false;
}
std::this_thread::sleep_for(std::chrono::milliseconds(1000));
if(threadExit){
break;
}
{
std::unique_lock<std::mutex> lock(mutex);
performProc= true;
}
condVar.notify_one();
}
Please note the variable threadExit is set by the main thread under the mutex lock and notified to worker thread. The timer thread can see this flag when it wakes up(which should be fine for my implementation)
Do you think performProc may set to false again before the worker thread sees it as true? If yes, can you please throw some light on how to tackle this problem? Thanks!
Unless threadExit is atomic, the code exhibits undefined behavior (race condition). All accesses to threadExit must be protected by a mutex, so also reads in while(!threadExit) and if(threadExit)....
But there's no need to do any of this. You can run everything in the same thread if you use sleep_until (and a steady clock) instead of sleep_for.
#include <chrono>
#include <iostream>
#include <thread>
using namespace std::literals;
void do_work() {
std::cout << "Work # " << std::chrono::system_clock::now() << std::endl;
}
int main() {
while (true) {
auto t = ceil<std::chrono::seconds>(std::chrono::steady_clock::now() + 600ms);
std::this_thread::sleep_until(t);
do_work();
}
}
Output:
Work # 2022-03-04 09:56:51.0148904
Work # 2022-03-04 09:56:52.0134687
Work # 2022-03-04 09:56:53.0198704
Work # 2022-03-04 09:56:54.0010437
Work # 2022-03-04 09:56:55.0148975
. . .

Modern C++. Return data structure from working thread continuing its execution

I need to launch working thread, perform some initialization, return data structure as initialization result and continue thread execution. What is the best (or possible) code to achieve this using modern c++ features only? Note, launched thread should continue its execution (thread does not terminated as usual). Unfortunately, most solutions assume worker thread termination.
Pseudo code:
// Executes in WorkerThread context
void SomeClass::Worker_treadfun_with_init()
{
// 1. Initialization calls...
// 2. Pass/signal initialization results to caller
// 3. Continue execution of WorkerThread
}
// Executes in CallerThread context
void SomeClass::Caller()
{
// 1. Create WorkerThread with SomeClass::Worker_treadfun_with_init()" thread function
// 2. Sleep thread for some initialization results
// 3. Grab results
// 3. Continue execution of CallerThread
}
I think std::future meets your requirements.
// Executes in WorkerThread context
void SomeClass::Worker_treadfun_with_init(std::promise<Result> &pro)
{
// 1. Initialization calls...
// 2. Pass/signal initialization results to caller
pro.set_value(yourInitResult);
// 3. Continue execution of WorkerThread
}
// Executes in CallerThread context
void SomeClass::Caller()
{
// 1. Create WorkerThread with SomeClass::Worker_treadfun_with_init()" thread function
std::promise<Result> pro;
auto f=pro.get_future();
std::thread([this,&pro](){Worker_treadfun_with_init(pro);}).detach();
auto result=f.get();
// 3. Grab results
// 3. Continue execution of CallerThread
}
Try using a pointer or reference to the data structure with the answer in it, and std::condition_variable to let you know when the answer has been computed:
#include <iostream>
#include <thread>
#include <mutex>
#include <condition_variable>
#include <chrono>
#include <vector>
std::vector<double> g_my_answer;
std::mutex g_mtx;
std::condition_variable g_cv;
bool g_ready = false;
void Worker_treadfun_with_init()
{
//Do your initialization here
{
std::unique_lock<std::mutex> lck( g_mtx );
for( double val = 0; val < 10; val += 0.3 )
g_my_answer.push_back( val );
g_ready = true;
lck.unlock();
g_cv.notify_one();
}
//Keep doing your other work..., here we'll just sleep
for( int i = 0; i < 100; ++i )
{
std::this_thread::sleep_for( std::chrono::seconds(1) );
}
}
void Caller()
{
std::unique_lock<std::mutex> lck(g_mtx);
std::thread worker_thread = std::thread( Worker_treadfun_with_init );
//Calling wait will cause current thread to sleep until g_cv.notify_one() is called.
g_cv.wait( lck, [&g_ready](){ return g_ready; } );
//Print out the answer as the worker thread continues doing its work
for( auto val : g_my_answer )
std::cout << val << std::endl;
//Unlock mutex (or better yet have unique_lock go out of scope)
// incase worker thread needs to lock again to finish
lck.unlock();
//...
//Make sure to join the worker thread some time later on.
worker_thread.join();
}
Of course in actual code you wouldnt use global variables, and instead pass them by pointer or reference (or as member variables of SomeClass) to the worker function, but you get the point.

C++ thread that starts several threads

I am trying to do a program that has to run 2 tasks periodically.
That is, for example, run task 1 every 10 seconds, and run task 2 every 20 seconds.
What I am thinking is to create two threads, each one with a timer. Thread 1 launches a new thread with task 1 every 10 seconds. and Thread 2 launches a new thread with task 2 every 20 seconds.
My doubt is, how to launch a new task 1 if the previous task 1 hasn't finished?
while (true)
{
thread t1 (task1);
this_thread::sleep_for(std::chrono::seconds(10));
t1.join();
}
I was trying this, but this way it will only launch a new task 1 when the previous one finishes.
EDIT:
Basically I want to implement a task scheduler.
Run task1 every X seconds.
Run task2 every Y seconds.
I was thinking in something like this:
thread t1 (timer1);
thread t2 (timer2);
void timer1()
{
while (true)
{
thread t (task1);
t.detach()
sleep(X);
}
}
the same for timer2 and task2
Perhaps you could create a periodic_task handler that is responsible for scheduling one task every t seconds. And then you can launch a periodic_task with a specific function and time duration from anywhere you want to in your program.
Below I've sketched something out. One valid choice is to detach the thread and let it run forever. Another is to include cancellation to allow the parent thread to cancel/join. I've included functionality to allow the latter (though you could still just detach/forget).
#include <condition_variable>
#include <functional>
#include <iostream>
#include <mutex>
#include <thread>
class periodic_task
{
std::chrono::seconds d_;
std::function<void()> task_;
std::mutex mut_;
std::condition_variable cv_;
bool cancel_{false};
public:
periodic_task(std::function<void()> task, std::chrono::seconds s)
: d_{s}
, task_(std::move(task))
{}
void
operator()()
{
std::unique_lock<std::mutex> lk{mut_};
auto until = std::chrono::steady_clock::now();
while (true)
{
while (!cancel_ && std::chrono::steady_clock::now() < until)
cv_.wait_until(lk, until);
if (cancel_)
return;
lk.unlock();
task_();
lk.lock();
until += d_;
}
}
void cancel()
{
std::unique_lock<std::mutex> lk{mut_};
cancel_ = true;
cv_.notify_one();
}
};
void
short_task()
{
std::cerr << "short\n";
}
void
long_task(int i, const std::string& message)
{
std::cerr << "long " << message << ' ' << i << '\n';
}
int
main()
{
using namespace std::chrono_literals;
periodic_task task_short{short_task, 7s};
periodic_task task_long{[](){long_task(5, "Hi");}, 13s};
std::thread t1{std::ref(task_short)};
std::this_thread::sleep_for(200ms);
std::thread t2{std::ref(task_long)};
std::this_thread::sleep_for(1min);
task_short.cancel();
task_long.cancel();
t1.join();
t2.join();
}
You want to avoid using thread::join() it, by definition, waits for the thread to finish. Instead, use thread::detach before sleeping, so it doesn't need to wait.
I'd suggest reading up on it http://www.cplusplus.com/reference/thread/thread/detach/

How do I use while true in threads?

Can anyone point me at the thing I try to do in this code, because SecondLoop thread is unreachable at all? It becomes reachable only if I remove while(true) loop.
#include <iostream>
#include <thread>
using namespace std;
void Loop() {
while(true) {
(do something)
}
}
void SecondLoop() {
while(true) {
(do something)
}
}
int main() {
thread t1(Loop);
t1.join();
thread t2(SecondLoop);
t2.join(); // THIS THREAD IS UNREACHABLE AT ALL!
return false;
}
The reason why I use multithreading is because I need to get two loops running at the same time.
join blocks the current thread to wait for another thread to finish. Since your t1 never finishes, your main thread waits for it indefinitely.
Edit:
To run two threads indefinitely and concurrency, first create the threads, and then wait for both:
int main() {
thread t1(Loop);
thread t2(SecondLoop);
t1.join();
t2.join();
}
To run Loop and SecondLoop concurrency, you have to do something like:
#include <iostream>
#include <thread>
void Loop() {
while(true) {
//(do something)
}
}
void SecondLoop() {
while(true) {
//(do something)
}
}
int main() {
std::thread t1(Loop);
std::thread t2(SecondLoop);
t1.join();
t2.join();
}
as join block current thread to wait the other thread finishes.
.join() waits for the thread to end (so in this case if you break out of the while loops and exit the thread function)
using while(true) is linked to the tread running , you should look for a way to exit that loop, use some sort of loop control
Based on my comment and what #Nidhoegger answered I suggest:
int main() {
thread t1(Loop);
thread t2(SecondLoop);
// Your 2 threads will run now in paralel
// ... <- So some other things with your application
// Now you want to close the app, perhaps all work is done or the user asked it to quit
// Notify threads to stop
t1running = false;
t2running = false;
// Wait for all threads to stop
t1.join();
t2.join();
// Exit program
return false;
}

Basic timer with std::thread and std::chrono

I'm trying to implement a basic timer with the classic methods: start() and stop(). I'm using c++11 with std::thread and std::chrono.
Start method. Creates a new thread that is asleep for a given interval time, then execute a given std::function. This process is repeated while a 'running' flag is true.
Stop method. Just sets the 'running' flag to false.
I created and started a Timer object that show "Hello!" every second, then with other thread I try to stop the timer but I can't. The Timer never stops.
I think the problem is with th.join()[*] that stops execution until the thread has finished, but when I remove th.join() line obviously the program finishes before the timer start to count.
So, my question is how to run a thread without stop other threads?
#include <iostream>
#include <thread>
#include <chrono>
using namespace std;
class Timer
{
thread th;
bool running = false;
public:
typedef std::chrono::milliseconds Interval;
typedef std::function<void(void)> Timeout;
void start(const Interval &interval,
const Timeout &timeout)
{
running = true;
th = thread([=]()
{
while (running == true) {
this_thread::sleep_for(interval);
timeout();
}
});
// [*]
th.join();
}
void stop()
{
running = false;
}
};
int main(void)
{
Timer tHello;
tHello.start(chrono::milliseconds(1000),
[]()
{
cout << "Hello!" << endl;
});
thread th([&]()
{
this_thread::sleep_for(chrono::seconds(2));
tHello.stop();
});
th.join();
return 0;
}
Output:
Hello!
Hello!
...
...
...
Hello!
In Timer::start, you create a new thread in th and then immediately join it with th.join(). Effectively, start won't return until that spawned thread exits. Of course, it won't ever exit because nothing will set running to false until after start returns...
Don't join a thread until you intend to wait for it to finish. In this case, in stop after setting running = false is probably the correct place.
Also - although it's not incorrect - there's no need to make another thread in main to call this_thread::sleep_for. You can simply do so with the main thread:
int main()
{
Timer tHello;
tHello.start(chrono::milliseconds(1000), []{
cout << "Hello!" << endl;
});
this_thread::sleep_for(chrono::seconds(2));
tHello.stop();
}
Instead of placing the join in start place it after running = false in stop. Then the stop method will effectively wait until the thread is completed before returning.