Run boolean at start of thread causes jumping behaviour between instructions - c++

Foo.h
#pragma once
#include <stdint.h>
#include <cstddef>
#include <thread>
#include <mutex>
#include <shared_mutex>
#include <atomic>
class Foo: public FooAncestor
{
private:
std::atomic_bool start = false;
//I do a shared mutex on the currentValue,
//but I took it out in order to make sure that it was not part of the problem
mutable std::shared_mutex valueMutex;
float currentValue = 0.0;
public:
Foo();
void Start();
inline float GetValue() { return currentValue; }
};
Foo.cpp
#include "Foo.h"
using namespace std::chrono_literals;
Foo::Foo()
{
//setting up things not related to the subject
}
void Foo::Start()
{
std::thread updateThread( [=]()
{
start = true;
while( start )
{
//a whole bunch of commented out code which doesn't make any difference to this
std::this_thread::sleep_for( 200ms );
currentTemp += 1;
}
} );
updateThread.detach();
}
Main.cpp
int main()
{
std::cout << "hello from PiCBake!\n";
int i = 0;
//a bunch of additional setup code here, not related to this class
Foo foo = Foo();
foo.Start();
for( ;;)
{
//this part is just for testing of the class and has no actual function
std::cout << max.GetTemp() << std::endl;
delay( 500 );
if( ++i == 10 )
i = 0;
}
return 0;
}
Whenever I include this, or a separate test at the beginning of the updateThread part (like: if(!run) return;) the flow of the code does weird things. In debugging, it keeps jumping to the part where 'run' is being tested, even jumping out of the while loop when run is set in the thread, but the behavior is the same when run is set before the thread is created.
If the thread is very long it actually never gets to finish at all. Whenever I remove the variable 'run' and replace it with "true" all works as expected. If I replace the "while(run)" with "while(true)", but test 'run' right after in an if-statement, the same thing happens.
Tried making run atomic, tried a bunch of other things, removing everything etc.
Please note that I didn't yet implemented a thread-exit condition. "run" could be set to false in the destructor or something in order to quit the thread. But that's not really the issue.
Update:
It must have been late, and I was probably going around in circles. It seems that changing the start value to atomic already solved it, either way, it works and I have no ^&*() clue what was going wrong...

Related

Why does std::shared_ptr call my destructor twice?

In this program, why is the destructor on line 14 is called twice for the same instance of mystruct_t?
I'm assuming that all pointer manipulation in this program is thread safe. I think the atomic updates do not work on my system or compiler.
I tried this on MSVC 2017, MSVC 2019 and on clang
/* This crashes for me (line 19) */
#include <iostream>
#include <vector>
#include <thread>
#include <memory>
#include <chrono>
#include <assert.h>
struct mystruct_t {
int32_t nInvocation = 0;
~mystruct_t();
mystruct_t() = default;
};
mystruct_t::~mystruct_t() {
nInvocation++;
int nInvoke = nInvocation;
if (nInvoke > 1) {
/* destructor was invoked twice */
assert(0);
}
/* sleep is not necessary for crash */
//std::this_thread::sleep_for(std::chrono::microseconds(525));
}
std::shared_ptr<mystruct_t> globalPtr;
void thread1() {
for (;;) {
std::this_thread::sleep_for(std::chrono::microseconds(1000));
std::shared_ptr<mystruct_t> ptrNewInstance = std::make_shared<mystruct_t>();
globalPtr = ptrNewInstance;
}
}
void thread2() {
for (;;) {
std::shared_ptr<mystruct_t> pointerCopy = globalPtr;
}
}
int main()
{
std::thread t1;
t1 = std::thread([]() {
thread1();
});
std::thread t2;
t2 = std::thread([]() {
thread2();
});
for (int i = 0;; ++i) {
std::this_thread::sleep_for(std::chrono::microseconds(1000));
std::shared_ptr<mystruct_t> pointerCopy = globalPtr;
globalPtr = nullptr;
}
return 0;
}
As several users here already mentioned, you're running into undefined behavior since you globally (or foreign threaded) alter your referred object while thread-locally, you try to copy assign it. A drawback of the sharedPtr especially for newcomers is the quite hidden danger in the suggestion, you're always thread safe in copying them. As you do not use references, this can become even harder to see in doubt. Always try to see the shared_ptr as a regular class in the first place with a common ('trivial') member-wise copy assigment where interferences are always possible in non-protected threading environments.
If you're going to encounter similar situations with that or similar code in future, try to use a robust channeled broadcasting/event based scheme instead of locally placed locks! The channels (buffered or single data based) themselves care about the proper data lifetime then, ensuring the sharedPtr's underlying data 'rescue'.

how to run some method that will run on different thread every 2 seconds?

I want to write some code that on the main it will start some thread that will run every 2 seconds and will print something on the console.
the start function need to be something like this
void StartTask(void* methodRoRun, long repeatTimeInSeconds);
that mean that the method receive pointer to function (methodRoRun) that will run every repeatTimeInSeconds seconds.
I can't find how to do it in C++
Something like this:
#include <thread>
#include <functional>
void f() {
printf("Task started\n");
// do stuff
}
void StartTask(std::function<void()> methodRoRun, long repeatTimeInSeconds) {
std::thread th([methodRoRun, repeatTimeInSeconds]() {
while (true ) {
methodRoRun();
std::this_thread::sleep_for(std::chrono::seconds(repeatTimeInSeconds));
}
});
th.detach();
}
int main() {
StartTask([](){ f(); }, 1);
while (true) {}
return 0;
}
Edit:
People are correctly pointing out this that detaching threads and having endless loops is not good practice, but the example just illustrates the approach.

How to check if thread has finished work in C++11 and above?

How can I check if thread has finished work in C++11 and above? I have been reading the documentation and I have written the following code:
#include <iostream>
#include <thread>
void mythread()
{
//do some stuff
}
int main()
{
std::thread foo(mythread);
if (foo.joinable())
{
foo.join();
//do some next stuff
}
}
joinable tells only that the thread has started work, but I would like to know how to write code to check if the thread has finished work.
For example:
#include <iostream>
#include <thread>
void mythread()
{
//do some stuff
}
int main()
{
std::thread foo(mythread);
if (foo.finishedWork())
{
foo.join();
//do some next stuff
}
}
You may want to use std::future, it provides higher level facilities where you can trivially check if the asynchronous computation is finished (aka ready): Example:
void mythread() {
//do some stuff
}
template<typename T>
bool future_is_ready(std::future<T>& t){
return t.wait_for(std::chrono::seconds(0)) == std::future_status::ready;
}
int main()
{
std::future<void> foo = std::async(std::launch::async, mythread);
if (future_is_ready(foo)){
//do some next stuff
}
}
On the other hand, you may think simply using a "safe" (or atomic) flag works:
#include <iostream>
#include <thread>
std::atomic<bool> is_done{false};
void mythread()
{
//do some stuff
......
is_done = true;
}
int main()
{
std::thread foo(mythread);
if (is_done)
{
foo.join();
//do some next stuff
}
.....
if(foo.joinable()) foo.join();
}
But, it doesn't work. While you think is_done = true is the last thing you did in mythread(); You may have created some objects of automatic storage duration in that scope, and since such objects are destroyed in the reverse order of construction, there will still be "some work" in that thread after setting is_done.
You want a future. Start your thread withstd::async and use wait_for with zero seconds on it. Compare the result against future_status::ready.
You can use wait_for of std::future to check whether the result is already there. A simple way to get a future for an asynchronous task is std::async.
#include <future>
// ...
// launch task and get result future
auto rf = std::async(std::launch::async, mythread);
// get initial status
auto status = rf.wait_for(std::chrono::nanoseconds(1));
// loop while task is not ready
while(status != std::future_status::ready)
{
// not ready yet, do other stuff here
// 1 nanosecond timeout check
status = rf.wait_for(std::chrono::nanoseconds(1));
}
// we are done...
I had the same problem, and my solution was to wrap the thread class, so I can set a flag when the function has finished its work.
Here you find the discussion for the solution Stack Overflow
And here is the working example: Celma managed thread

Very simple method with QtConcurrentRun and mutex sometimes gives segmentation fault

I want to know what is wrong with this code. Sometimes I get sementation fault, sometimes not. This is a problem that I have in a greater piece of software, the idea is that just one thread at the same time is executing the method MyClass::print. Even with this simple example, it fail with segmentation fault. What is wrong in the code? How I can solve the problem?
Thanks!
#include <iostream>
#include <ctime>
#include <QMutex>
#include <QtConcurrentRun>
class MyClass : QThread {
public:
void print(std::string str) {
mutex.lock();
std::cout << "In some thread: " << str << "\n";
mutex.unlock();
}
private:
QMutex mutex;
};
int main() {
MyClass myCl;
for(int i=0; i < 10; i++) {
QtConcurrent::run(&myCl, &MyClass::print,std::string("bla"));
}
}
You do not join your threads after the for cycle that spawns them.
Therefore, the main() function may end before all the threads have finished. This would make myCl go out of scope, and the threads would be trying to access an object that has been destroyed (in particular, its mutex variable). Which gives you Undefined Behavior.
Things should get better if you joined your threads before exiting from main() (or find any other way of not exiting from main() as long as any of the threads is still running).

From boost::threads to boost::asio timers

In my project every class object has its own thread with infinite cycle (while(1)) inside, in which particular object functions are performed. And I'm trying to change this so that every object would perform its functions asynchronously with timers.
Basically this is how it works with thread with infinite loop:
class obj
{
public:
obj();
~obj();
//custom functions and variables
int x;
int obj_action;
move();
wait();
}
obj()
{
obj_action=1;
//when constructing object, make its thread with infinite while cycle
boost::thread make_thread(boost::bind(&obj::obj_engine,this));
}
void obj::obj_engine()
{
while(true)
{
if (obj_action==1){move();}
else if (obj_action==2){wait();}
Sleep(1);
}
}
void obj::move()
{
x++;
obj_action==2;
}
void obj::wait()
{
Sleep(5000);
obj_action==1;
}
This example shows, the obj class, which has constructor , destructor, couple of variables and couple of functions.
When constructing an object (obj()), thread is made. Thread contains a function "obj_engine" , which has infinite loop (while(true)). In the loop there is two functions:
1. wait() - makes a thread sleep for 5 seconds.
2. walk() - simply x+1
those 2 functions switches each other after its end by defining obj_action.
Now I want to change this to, when the constructing and object , asynchronously move() function would be performed, and after move() function, asynchronously wait() function would be performed, and vice verse. So I wouldn't need to use any threads.
I hoping for result like this:
//constructing
obj()
{
asynchronous(walk());
}
walk()
{
x++
asynchronous(wait());
}
wait()
{
Sleep(5000);
asynchronous(walk());
}
I heard you can do this, with boost::asio timers , but I really don't know how.
I would be very grateful if someone would show me how.
Here you go:
#include <boost/asio.hpp>
#include <boost/date_time/posix_time/posix_time.hpp>
#include <boost/bind.hpp>
#include <iostream>
class obj {
public:
obj() : x_(0), t_(io_service_, boost::posix_time::seconds(5)) {
t_.async_wait(boost::bind(&obj::move, this));
io_service_.run();
}
void move() {
x_++;
std::cout << x_ << std::endl;
t_.expires_at(t_.expires_at() + boost::posix_time::seconds(5));
t_.async_wait(boost::bind(&obj::move, this));
}
private:
int x_;
boost::asio::io_service io_service_;
boost::asio::deadline_timer t_;
};
int main(int, char**) {
obj a;
while(true);
}
Basically everything you need is covered by the asio tutorial: this tutorial shows you how to use an asynchronous timer, and this tutorial shows you how to reset your timer.
Update:
Please use the above source code instead of my initial one - due to the repetitive calls of io_service_.run(), each move call would be called in another thread and after some time your application would crash because of it. The above code fixes this problem, and gets rid of the wait function by doing so.
Borrowing the example from nijansen, I've whipped together something that should be more similar to what you want (I think).
The key here is the io_service should be shared between all object's scheduling on it. Usually there is one io_service per thread, but more intricate schemes can be used as well. io_service::run runs for as long as there is work scheduled on the io_service (pending timeout or waiting on a socket). When no more work is scheduled, it simply returns.
You might be interested in io_service::post as a way to send messages between your "active objects" (which works even if they are running under different io_services and different threads). You may want to look at boost::bind and possibly boost::signals.
#include <boost/asio.hpp>
#include <boost/date_time/posix_time/posix_time.hpp>
#include <boost/bind.hpp>
#include <iostream>
namespace asio = boost::asio;
class obj {
public:
obj(asio::io_service& ioSvc)
: x_(0), t_(ioSvc)
{
schedule_in(5);
}
void schedule_in(int seconds) {
t_.expires_from_now(boost::posix_time::seconds(3));
t_.async_wait(boost::bind(&obj::move, this));
}
void move() {
x_++;
std::cout << x_ << std::endl;
schedule_in(5);
}
private:
int x_;
boost::asio::deadline_timer t_;
};
int main(int, char**) {
boost::asio::io_service io_service;
obj a(io_service);
obj b(io_service);
obj c(io_service);
io_service.run();
}