How to start a boost::thread running a member function? - c++

I have a real time controller application with a number of hardware devices of different types connected.
All devices share a lot of code, but each has also some device type specific stuff. I'm trying to write this code to be easy to extend with new types of hw.
Each connected device should have an event manager function running in a separate thread.
I would like to keep the common stuff in a base class, lets call it "Device" and just put the hardware specific code in the derived classes.
So I create a Device base class with the common stuff and make the event manager a pure virtual, and then each derived class implements it.
Then at system start I create a vector of all the connected hardware devices, and push pointers to instances of the appropriate derived class into it.
Now I would like to start a boost::thread for each instance in the vector, and each thread should execute the event manager function from that instance in the vector.
So I try something like:
Class Device {
...
boost::thread thread;
void manager() = 0;
...
}
Class SpecificDevice1 : public Device {
...
void manager();
}
SpecificDevice1::manager() {
...do stuff here...
}
Class SpecificDevice2 : public Device {
...
void manager();
}
SpecificDevice2::manager() {
...do stuff here...
}
Class Config {
...
std::vector<Device*> devices;
...
}
Config config;
...config.devices get populated with pointers to instances of SpecificDevice1 and SpecificDevice2...
for( auto &device : config.devices ) {
device->thread = boost::thread( device->manager );
};
I have tried many different permutation of this but I always end up with
error: no matching function for call to 'boost::thread::thread()'
...even if I dynamic_cast device to a pointer to the appropriate SpecificDeviceX class, I still get the same error.

The boost::thread constructor needs a function pointer, and an instance to the actual object (for the this pointer in the member function).
For this use can use the Thread Constructor with arguments:
device->thread = boost::thread(&Device::manager, device);
The first argument is a pointer to the member function, and the second is a pointer to an instance of Device.
There is another change you must do for this to work though, and that is to make the manager function virtual, for the proper function would be called:
Class Device {
...
boost::thread thread;
virtual void manager() = 0;
...
}
By the way, since you are using a compiler supporting C++11, I suggest you change to std::thread if possible.

Related

C++ freertos Call overriden function of base class from subclass after getting semaphore failes

I am trying to make a base class that holds a semaphore and wait until it can take the semaphore and then call a function in a derived class. (I want to have a number of different base classes that implement the function different but all of them schuld execute this function only after acquiring the semaphore.
I am not very familiar with freertos, so i think probably the error is related to that.
I made some attempts but so far with no success.
Here is the basic code:
The Base class:
class CommandMode{
public:
CommandMode(xSemaphoreHandle* smphr_calc_steps);
virtual ~CommandMode(){};
virtual int GetNextState()=0;
protected:
static void TSK_CalcSteps(void* params);
xSemaphoreHandle* smphr_calc_steps;
virtual void CalculateSteps(){};
};
CommandMode::CommandMode(xSemaphoreHandle* smphr_calc_steps):smphr_calc_steps(smphr_calc_steps){
xTaskCreate(&TSK_CalcSteps, "output data calc", 2048, this, 1, NULL);
}
void CommandMode::TSK_CalcSteps(void* params){
CommandMode* cm = (CommandMode*) params;
while(true){
//force reevaluation at least every 60s
xSemaphoreTake(cm->smphr_calc_steps, 60*1000/portTICK_PERIOD_MS); // i think the problem is related to that line
cm->CalculateSteps();
}
}
and here the derived class:
class Mode1:public CommandMode{
public:
Mode1(xSemaphoreHandle* smphr_calc_steps);
~Mode1(){};
int GetNextState() override;
protected:
void CalculateSteps() override;
};
Mode1::Mode1(xSemaphoreHandle* smphr_calc_steps) : CommandMode(smphr_calc_steps){}
void Mode1::CalculateSteps(){
Serial.println("Mode1::CalculateSteps");
}
int Mode1::GetNextState(){
Serial.println("Mode1::GetNextState");
return 5;
}
Then i try to invoke them similar to this:
CommandMode* current = nullptr;
xSemaphoreHandle smphr = xSemaphoreCreateBinary();
//xSemaphoreHandle smphr2 = xSemaphoreCreateBinary();
Serial.println("init with mode1");
delay(200);
Mode1* a = new Mode1(&smphr);
a->GetNextState(); //This will work
current = a;
current->GetNextState(); //This will work as well
xSemaphoreGive(smphr); //This does not work as intended/causes the issue
Im also not sure about the line cm->CalculateStepes(). Since i passed 'cm' as a void* will it still be evaluating the correct subclass's module? I am running this on an ESP32 with Plattform IO in case this is important.
So far i sometimes got a watchdog error, but mostly i get the following two errors:
/home/runner/work/esp32-arduino-lib-builder/esp32-arduino-lib-builder/esp-idf/components/freertos/queue.c:1443 (xQueueGenericReceive)- assert failed!
abort() was called at PC 0x40087f1d on core 0
assertion "res == coreID || res == portMUX_FREE_VAL" failed: file "/home/runner/work/esp32-arduino-lib-builder/esp32-arduino-lib-builder/esp-idf/components/freertos/portmux_impl.inc.h", line 105, function: vPortCPUAcquireMutexIntsDisabledInternal
abort() was called at PC 0x400d8cf3 on core 0
I tried use the whole code out of a task itself and experimented with multiple delays(), but I never got it working.
I would be glad if someone could tell me where the problem is, or has a suggestion how to implement this behavior in a better way?
I want to have other functions and values in the base class as well. This works without a problem but the calling of the derived class's function based upon the semaphore is not working at all.
xSemaphoreTake expects the handle to be passed by value, you pass it by pointer, that is definitely wrong.
The code compiles because SemaphoreHandle_t itself is a hidden pointer (hence this not being a good practice, but occurs often in low-level stuff for other good reasons). This also means that you can and should pass and store smphr_calc_steps as a value in your class, being a pointer its cheap to copy. The extra indirection is not needed and only complicates stuff.
FreeRTOS allocates the semaphore on the heap and returns a pointer(=the handle) to you, your only responsibility is to call vSemaphoreDelete sometime in the future to free up the memory.

Pass data between threads using boost.signals2

I apologize for the ambiguous title, but I'll try to elaborate further here:
I have an application which includes (among others) a control, and TCP server classes.
Communication between the TCP and control class is done via this implementation:
#include <boost/signals2.hpp>
// T - Observable object type
// S - Function signature
template <class T, typename S> class observer {
using F = std::function<S>;
public:
void register_notifier(T &obj, F f)
{
connection_ = obj.connect_notifier(std::forward<F>(f));
}
protected:
boost::signals2::scoped_connection connection_;
};
// S - Function signature
template <typename S> class observable {
public:
boost::signals2::scoped_connection connect_notifier(std::function<S> f)
{
return notify.connect(std::move(f));
}
protected:
boost::signals2::signal<S> notify;
};
Where the TCP server class is the observable, and the control class is the observer.
The TCP server is running on a separate thread from the control class, and uses boost::asio::async_read. Whenever a message is received, the server object sends a notification via the 'notify' member, thus triggering the callback registered in the control class, and then waits to read the next message.
The problem is that I need to somehow safely and efficiently store the data currently stored in the TCP server buffer and pass it to the control class before it's overridden by the next message.
i.e. :
inline void ctl::tcp::server::handle_data_read(/* ... */)
{
if (!error) {
/* .... */
notify(/* ? */); // Using a pointer to the buffer
// would obviously fail as it
// is overridden in the next read
}
/* .... */
}
Those were my ideas for a solution so far:
Allocating heap memory and passing a pointer to it using
unique_ptr, but I'm not sure if boost.signals2 is move-aware.
Use an
unordered map (shared between the objects) that maps an integer index to a unique_ptr of the
data type (std::unordered_map<int, std::unique_ptr<data_type>>),
then only pass the index of the element, and 'pop' it in the control
class callback, but it feels like an overkill.
What I'm really looking for is an idea for a simple and efficient solution to pass the TCP buffer contents for each message between the threads.
Note I'm also open for suggestions to redesign my communication method between the objects if it's completely wrong.

Object with its own thread and thread from inheritance?

I have two objects
class Protocol : public UDPServer, private Thread { void loop(); ... };
class UDPServer : private Thread { void loop(); ... };
where Thread is a class which will call the object's loop-method in its own thread and where UDPServer will call a notify()-function in Protocol whenever it receives a new message.
Each of the two objects should run its own loop() during runtime (hence the two Thread-inheritances). According to this thread, this is not possible the way I wrote it.
I now wonder if I have to copy and rename the Thread-class to solve this problem or whether there's another workaround? I could probably solve this with two separate objects and circular inheritance but this would make the code somewhat more complex ...

Communication between 2 threads C++ UNIX

I need your help with wxWidgets. I have 2 threads (1 wxTimer and 1 wxThread), I need communicate between this 2 threads. I have a class that contains methods to read/write variable in this class. (Share Memory with this object)
My problem is: I instanciate with "new" this class in one thread but I don't know that necessary in second thread. Because if instanciate too, adress of variable are differents and I need communicate so I need even value in variable :/
I know about need wxSemaphore to prevent error when to access same time.
Thanks you for your help !
EDIT: My code
So, I need make a link with my code. Thanks you for all ;)
It's my declaration for my wxTimer in my class: EvtFramePrincipal (IHM)
In .h
EvtFramePrincipal( wxWindow* parent );
#include <wx/timer.h>
wxTimer m_timer;
in .cpp -Constructor EvtFramePrincipal
EvtFramePrincipal::EvtFramePrincipal( wxWindow* parent )
:
FramePrincipal( parent ),m_timer(this)
{
Connect(wxID_ANY,wxEVT_TIMER,wxTimerEventHandler(EvtFramePrincipal::OnTimer),NULL,this);
m_timer.Start(250);
}
So I call OnTimer method every 250ms with this line.
For my second thread start from EvtFramePrincipal (IHM):
in .h EvtFramePrincipal
#include "../Client.h"
Client *ClientIdle;
in .cpp EvtFramePrincipal
ClientIdle= new Client();
ClientIdle->Run();
In .h Client (Thread)
class Client: public wxThread
public:
Client();
virtual void *Entry();
virtual void OnExit();
In .cpp Client (Thread)
Client::Client() : wxThread()
{
}
So here, no probleme, thread are ok ?
Now I need that this class that use like a messenger between my 2 threads.
#ifndef PARTAGE_H
#define PARTAGE_H
#include "wx/string.h"
#include <iostream>
using std::cout;
using std::endl;
class Partage
{
public:
Partage();
virtual ~Partage();
bool Return_Capteur_Aval()
{ return Etat_Capteur_Aval; }
bool Return_Capteur_Amont()
{ return Etat_Capteur_Amont; }
bool Return_Etat_Barriere()
{ return Etat_Barriere; }
bool Return_Ouverture()
{ return Demande_Ouverture; }
bool Return_Fermeture()
{ return Demande_Fermeture; }
bool Return_Appel()
{ return Appel_Gardien; }
void Set_Ouverture(bool Etat)
{ Demande_Ouverture=Etat; }
void Set_Fermeture(bool Etat)
{ Demande_Fermeture=Etat; }
void Set_Capteur_Aval(bool Etat)
{ Etat_Capteur_Aval=Etat; }
void Set_Capteur_Amont(bool Etat)
{ Etat_Capteur_Amont=Etat; }
void Set_Barriere(bool Etat)
{ Etat_Barriere=Etat; }
void Set_Appel(bool Etat)
{ Appel_Gardien=Etat; }
void Set_Code(wxString valeur_code)
{ Code=valeur_code; }
void Set_Badge(wxString numero_badge)
{ Badge=numero_badge; }
void Set_Message(wxString message)
{
Message_Affiche=wxT("");
Message_Affiche=message;
}
wxString Get_Message()
{
return Message_Affiche;
}
wxString Get_Code()
{ return Code; }
wxString Get_Badge()
{ return Badge; }
protected:
private:
bool Etat_Capteur_Aval;
bool Etat_Capteur_Amont;
bool Etat_Barriere;
bool Demande_Ouverture;
bool Demande_Fermeture;
bool Appel_Gardien;
wxString Code;
wxString Badge;
wxString Message_Affiche;
};
#endif // PARTAGE_H
So in my EvtFramePrincipal(wxTimer), I make a new for this class. But in other thread (wxThread), what I need to do to communicate ?
If difficult to understand so sorry :/
Then main thread should create first the shared variable. After it, you can create both threads and pass them a pointer to the shared variable.
So, both of them, know how interact with the shared variable. You need to implement a mutex or wxSemaphore in the methods of the shared variable.
You can use a singleton to get access to a central object.
Alternatively, create the central object before creating the threads and pass the reference to the central object to threads.
Use a mutex in the central object to prevent simultaneous access.
Creating one central object on each thread is not an option.
EDIT 1: Adding more details and examples
Let's start with some assumptions. The OP indicated that
I have 2 threads (1 wxTimer and 1 wxThread)
To tell the truth, I know very little of the wxWidgets framework, but there's always the documentation. So I can see that:
wxTimer provides a Timer that will execute the wxTimer::Notify() method when the timer expires. The documentation doesn't say anything about thread-execution (although there's a note A timer can only be used from the main thread which I'm not sure how to understand). I can guess that we should expect the Notify method will be executed in some event-loop or timer-loop thread or threads.
wxThread provides a model for Thread execution, that runs the wxThread::Entry() method. Running a wxThread object will actually create a thread that runs the Entry method.
So your problem is that you need same object to be accessible in both wxTimer::Notify() and wxThread::Entry() methods.
This object:
It's not one variable but a lot of that store in one class
e.g.
struct SharedData {
// NOTE: This is very simplistic.
// since the information here will be modified/read by
// multiple threads, it should be protected by one or more
// mutexes
// so probably a class with getter/setters will be better suited
// so that access with mutexes can be enforced within the class.
SharedData():var2(0) { }
std::string var1;
int var2;
};
of which you have somewhere an instance of that:
std::shared_ptr<SharedData> myData=std::make_shared<SharedData>();
or perhaps in pointer form or perhaps as a local variable or object attribute
Option 1: a shared reference
You're not really using wxTimer or wxThread, but classes that inherit from them (at least the wxThread::Entry() is pure virtual. In the case of wxTimer you could change the owner to a different wxEvtHandler that will receive the event, but you still need to provide an implementation.
So you can have
class MyTimer: public wxTimer {
public:
void Notify() {
// Your code goes here
// but it can access data through the local reference
}
void setData(const std::shared_ptr<SharedData> &data) {
mLocalReference=data
}
private:
std::shared_ptr<SharedData> mLocalReferece
};
That will need to be set:
MyTimer timer;
timer.setData(myData);
timer.StartOnece(10000); // wake me up in 10 secs.
Similarly for the Thread
class MyThread: public wxThread {
public:
void Entry() {
// Your code goes here
// but it can access data through the local reference
}
void setData(const std::shared_ptr<SharedData> &data) {
mLocalReference=data
}
private:
std::shared_ptr<SharedData> mLocalReferece
};
That will need to be set:
MyThread *thread=new MyThread();
thread->setData(myData);
thread->Run(); // threads starts running.
Option2 Using a singleton.
Sometimes you cannot modify MyThread or MyTimer... or it is too difficult to route the reference to myData to the thread or timer instances... or you're just too lazy or too busy to bother (beware of your technical debt!!!)
We can tweak the SharedData into:
struct SharedData {
std::string var1;
int var2;
static SharedData *instance() {
// NOTE that some mutexes are needed here
// to prevent the case where first initialization
// is executed simultaneously from different threads
// allocating two objects, one of them leaked.
if(!sInstance) {
sInstance=new SharedData();
}
return sInstance
}
private:
SharedData():var2(0) { } // Note we've made the constructor private
static SharedData *sInstance=0;
};
This object (because it only allows the creation of a single object) can be accessed from
either MyTimer::Notify() or MyThread::Entry() with
SharedData::instance()->var1;
Interlude: why Singletons are evil
(or why the easy solution might bite you in the future).
What is so bad about singletons?
Why Singletons are Evil
Singletons Are Evil
My main reasons are:
There's one and only one instance... and you might think that you only need one now, but who knows what the future will hold, you've taken an easy solution for a coding problem that has far reaching consequences architecturally and that might be difficult to revert.
It will not allow doing dependency injection (because the actual class is used in the accessing the object).
Still, I don't think is something to completely avoid. It has its uses, it can solve your problem and it might save your day.
Option 3. Some middle ground.
You could still organize your data around a central repository with methods to access different instances (or different implementations) of the data.
This central repository can be a singleton (it is really is central, common and unique), but is not the shared data, but what is used to retrieve the shared data, e.g. identified by some ID (that might be easier to share between the threads using option 1)
Something like:
CentralRepository::instance()->getDataById(sharedId)->var1;
EDIT 2: Comments after OP posted (more) code ;)
It seems that your object EvtFramePrincipal will execute both the timer call back and it will contain the ClientIdle pointer to a Client object (the thread)... I'd do:
Make the Client class contain a Portage attribute (a pointer or a smart pointer).
Make the EvtFramePrincipal contain a Portage attribute (a pointer or smart pointer). I guess this will have the lifecycle of the whole application, so the Portage object can share that lifecycle too.
Add Mutexes locking to all methods setting and getting in the Portage attribute, since it can be accessed from multiple threads.
After the Client object is instantiated set the reference to the Portage object that the EvtFramePrincipal contains.
Client can access Portage because we've set its reference when it was created. When the Entry method is run in its thread it will be able to access it.
EvtFramePrincipal can access the Portage (because it is one of its attributes), so the event handler for the timer event will be able to access it.

Alternative to postThreadMessage/peekmessage?

There's a (static) thread in my C++ application, frequently doing something. To exchange information between the thread and my application I use methods PostThreadMessage and PeekMessage.
Due to some reason I can't use these methods anymore but don't know a good alternative. Does anybody have an advice? I just want to exchange simple parameters.
There's no reason why you can't "exchange simple object with the main thread" as you said in a comment. A common pattern for sharing an instance of a class between threads is to do something like this:-
Declare your class with a static function that can be targeted by _beginthread and an instance function that does the work:
class CMyClass
{
// ... other class declarations ...
private:
static void __cdecl _ThreadInit(void *pParam); // thread initial function
void ThreadFunction(); // thread instance function
void StartThread(); // function to spawn a thread
// ... other class declarations ...
};
Define the functions something like this:
void CMyClass::StartThread()
{
// function to spawn a thread (pass a pointer to this instance)
_beginthread(CMyClass::_ThreadInit, 0, this);
}
void __cdecl CMyClass:_ThreadInit(void *pParam)
{
// thread initial function - delegate to instance
CMyClass *pInstance = (CMyClass*)pParam;
pInstance->ThreadFunction();
}
void CMyClass:ThreadFunction()
{
// thread instance function is running on another
// thread but has (hopefully synchronised) access
// to all of the member variables of the CMyClass
// that spawned it ....
}
Makes sense? The general idea is just to use the static function with a passed this pointer to connect back to a specific instance of the class.