Threading Error static assertion failed C++ - c++

I am actually doing a programm to simulate stuffs in c++ , However I have a big problem which is :
error: static assertion failed: std::thread arguments must be invocable after conversion to rvalues|
I did actually made a lot of research but nothing came out and I dont know at all what to do my error is for std::thread AppliWaitThd(AppliMsgWait()); who is not a class and I dont know how to make it work. AppliMsgWait is just a while loop with action inside.
here is my code
#include "../Include/classglConfigCtx.h"
#include "../Include/SupSrv.h"
#include "../Include/ClassRadMgr.h"
#include "../Include/globalDefine.h"
#include "../Include/structGesCan.h"
#include "../Include/AppliMsg.h"
#include "../Include/AppliSNMP.h"
#include "../Include/GesCanSlot.h"
#include "../Include/GesCanSrv.h"
int main (){
SupSrv SupSrvFile("V0", "SupSrV.txt" );
ConfigClass ConfigCtx;
RadMgr RadioManager;
AppliMsgInit();
role InitRole ;
InitRole = ConfigCtx.ConfigClassGetrole_();
if (InitRole==masterRole)
{
GesCanSrvInit();
GesCanSlotInit();
};
std::thread RadMgrThd(&RadMgr::RadMgrWaitEvt,&RadioManager);
std::thread AppliWaitThd(AppliMsgWait());
std::thread AppliSNMPWaitThd(AppliSNMPWait());
if(InitRole==masterRole)
{
std::thread GesCanSrvThd(GesCanSrvRecvMsg());
std::thread GesCanSlotThd(GesCanSlotPeriod());
};
RadMgrThd.join();
AppliWaitThd.join();
AppliSNMPWaitThd.join();
//GesCanSrvThd.join();
//GesCanSlotThd.join();
return 0;
};
Here is my function
int AppliMsgWait(){
while(1)
{
// vérification des données du contexte de config?
if(ConfigCtx.ConfigClassGetFlagChangeAddr_()==true) {
auto newNetCastAddr= ConfigCtx.ConfigClassGetnetCastAddr_();
auto newNeighCastAddr = ConfigCtx.ConfigClassGetneighCastAddr_();
serverAddress.sin_addr.s_addr= inet_addr(newNeighCastAddr.c_str());
ConfigCtx.ConfigClassSetFlagChangeAddr_(false);
}
else if(glCSMAMsgToSCOMLst.size()>0) {
AppliMsgSendSCOM();
}
else {
AppliMsgRecvSCOM();
}
std::this_thread::sleep_for(std::chrono::milliseconds(10));
}//While
return 1 ;
}//end func

Related

Several Error with Implementing of Threads in QT [C++]

I'm new to implementing Threads in QT and even after reading the Documentation several times and watching Videos, I get some Error which not even Google can help me with.
thread.cpp:14: error: C2440: "Initialisierung": "QFuture" kann nicht in "QFuture" konvertiert werden
Error Codes are in German, tried to change QT Language, but didn't change the Language of the Errors. I can translate them if needed.
It seems the Error happens in this QFuture<int> future = QtConcurrent::run(&Thread::GenerateTable); command, even thought I wrote it 1:1 like from the QT Documentation.
Here is the Code I want to put in a Thread, as you can see it's writing a bit bunch of Numbers into a File, which takes around a Minute.
Thread.h
#ifndef THREAD_H
#define THREAD_H
#include <QObject>
#include <QFuture>
#include <QtConcurrent/QtConcurrent>
class Thread : public QObject
{
Q_OBJECT
public:
explicit Thread(QObject *parent = nullptr);
static bool start();
private:
int GenerateTable();
};
#endif // THREAD_H
Thread.cpp
#include "thread.h"
Thread::Thread(QObject *parent) : QObject(parent)
{
}
bool Thread::start()
{
QFuture<int> future = QtConcurrent::run(&Thread::GenerateTable);
if (future.result() == 0){
return true;
}
else
return false;
}
int Thread::GenerateTable(){
QString Path = QDir::currentPath();
QFile file(Path + "/Table.csv");
if (!file.open(QFile::WriteOnly | QFile::Text)){
return -1;
}
else{
QTextStream stream(&file);
constexpr uint64_t upper = 10'000'000;
QVector<uint64_t> rando(upper);
std::iota(rando.begin(), rando.end(), 1);
std::shuffle(rando.begin(), rando.end(),
std::mt19937(std::random_device{}()));
for (uint32_t i = 0; i < 10'000'000; ++i) {
stream << rando[i] << ',' << '\n';
}
return 0;
}
}
Thread::GenerateTable() is a member function. It needs an object to work on. You are calling it (er .. passing it to QtConcurrent::run()) from the (static) Thread::start() and there's no Thread object to speak of.
Although you've tagged Qt6, I'll point at the Qt5 documentation for calling member functions: you can pass an object (pointer) which you'll need to allocate from somewhere.

implementation of asynchronous thread in c++

I am unable to find a correct usage of asynchronous thread in c++11.The thing i want to do is i want to spwan threads and each thread will function simultaneously without waiting for each other like thread.join(),which makes other thread to wait until the current thread is done with.So,is there any library in c++ which makes threads to run parallely doing their work simultaneously without having to wait for the other to complete.Actually the thing i want is i want to run each threads sumultaneously, so that they don't wait for the other to complete and its functionality is executed simultaneously without having to wait for others to finish .
Thanks,
Kushal
EDIT:
EDIT:: i am posting the code below
#include <signal.h>
#include <thread>
#include <algorithm>
#include <cstring>
#include <csignal>
#include "paho_client.h"
using namespace std;
vector<string> topic_container{"rpi2/temp","sense /bannana","sense/util","mqtt/temp","sense/temp","sense/pine","sense/fortis/udap"};
vector<paho_client> publisher;
vector<paho_client> subscriber;
int finish_thread=1;
void Onfinish(int signum){
finish_thread=0;
exit(EXIT_FAILURE);
}
int main(int argc, char** argv) {
signal(SIGINT, Onfinish);
int topic_index;
if(argc<3){
cout<<"the format of starting commandline argument is"<<endl;
exit(1);
}
while(finish_thread!=0){
//paho_client::get_library_handle();
if(strcmp(argv[1],"create_publisher")){
for(topic_index=0;topic_index<atoi(argv[2]);topic_index++){
thread pub_th;
pub_th = thread([ = ]() {
paho_client client("publisher", "192.168.0.102", "9876",
topic_container[topic_index].c_str());
client.paho_connect_withpub();
publisher.push_back(client);
});
pub_th.join();
}
vector<paho_client>::iterator it;
int publisher_traverse=0;
for(it=publisher.begin();it<publisher.end();publisher_traverse++){
publisher[publisher_traverse].increment_count();
publisher[publisher_traverse].get_count();
}
}
}
return 0;
}
After using async with future am getting the same behaviour as above please point me where am i going wrong
#include <signal.h>
#include <thread>
#include <algorithm>
#include <cstring>
#include <csignal>
#include <future>
#include "paho_client.h"
using namespace std;
vector<string> topic_container{"rpi2/temp","sense/apple","sense/bannana","sense/util","mqtt/temp","sense/temp","sense/pine","sense/fortis/udap"};
vector<paho_client> publisher;
vector<paho_client> subscriber;
int finish_thread=1;
void Onfinish(int signum){
finish_thread=0;
exit(EXIT_FAILURE);
}
int accumulate_block_worker_ret(int topic_index) {
//int topic_index=0;
paho_client client("publisher", "192.168.0.102", "9876",
topic_container[topic_index].c_str());
client.paho_connect_withpub();
publisher.push_back(client);
client.increment_count();
return client.get_count();
}
int main(int argc, char** argv) {
signal(SIGINT, Onfinish);
if(argc<3){
cout<<"the format of starting commandline argument is . /paho_client_emulate <create_publisher><count of publisher client to spawn>" <<endl;
exit(1);
}
while(finish_thread!=0){
// paho_client::get_library_handle();
int topic_index;
if(strcmp(argv[1],"create_publisher")){
for(topic_index=0;topic_index<atoi(argv[2]);topic_index++){
// thread pub_th;
// pub_th = thread([ = ]() {
future<int> f = async(std::launch::async,accumulate_block_worker_ret,topic_index);
// });
// pub_th.join();
cout<<"the returned value from future is"<<f.get()<<endl;
}
vector<paho_client>::iterator it;
int publisher_traverse=0;
for(it=publisher.begin();it<=publisher.end();publisher_traverse++){
cout<<"came here"<<endl;
publisher[publisher_traverse].increment_count();
publisher[publisher_traverse].get_count();
}
}
}
return 0;
}
i want to launch all the publisher clients first (as threads) and
later publish messages from each threads
The pub_th.join() is misplaced inside the loop where the threads are started, thus waiting for the termination of each thread before starting the next one. To let the threads run in parallel, just move the .join() outside that loop. Of course to access the threads after the loop body, they have to be stored somewhere, e. g. in a vector - for this, change the first for loop to
vector <thread> pub_threads;
for (topic_index=0; topic_index<atoi(argv[2]); topic_index++)
{
pub_threads.push_back(thread([ = ]() { /* whatever */ }));
}
and later when done:
for (auto &th: pub_threads) th.join();
Actually i am running infinite while inside every instance of
paho_client so the first thread is not completed …
that thread is run continously
Of course if never done, there's no point to .join().

Code fails to print out an entire string and ends abruptly

#include "IRSensor.h"
#include "Turret.h"
#include "StepperButtonController.h"
#include "LoadBottleButton.h"
LoadBottleButton go(A3,1000);
void setup()
{
Serial.begin(9600);
Serial.println("Port Open");
}
void loop()
{
if(go.Read())
{
go.Monitor();
}
}
Above is the Main code
#ifndef LoadBottleButton_cpp
#define LoadBottleButton_cpp
#include "Arduino.h"
#include "ScaleObject.h"
#include "LoadBottleButton.h"
#include "Turret.h"
#include "StepperButtonController.h"
ScaleObject* so;
Turret* tPointer;
LoadBottleButton::LoadBottleButton(int pin, int debounce):StepperButtonController(pin,debounce)
{
}
void LoadBottleButton::Monitor()
{
Serial.println("In Monitor");
while(tPointer->getTurret().BottleCenterState==false)
{
Serial.println("In Monitor While Loop");
tPointer->Start();
SETUP = true;
load = true;
unload = !so->getScale().Empty();
Serial.println(load);
Serial.println(unload);
Serial.println(!so->getScale().Empty());
if(unload)
{
unload=!so->getScale().Empty();
}
else if(load && !so->getScale().Empty())
{
load = !tPointer->BottleCentered();
}
if(!load && !unload && SETUP)
{
tPointer->Stop();
SETUP = false;
}
}
}
#endif
And above is the LoadBottleButtonClass.cpp file.
#ifndef Turret_cpp
#define Turret_cpp
//#include "HX711.h"
#include "Turret.h"
#include "Arduino.h"
#include "StepperButtonController.h"
#include "ScaleObject.h"
#include "IRSensor.h"
//StepperButtonController Clear(9,1000);
void StepTurret();
Turret turret(2,3,4,StepTurret);
void StepTurret()
{
turret.Step();
}
ScaleObject* tso;
IRSensor* irs;
Turret::Turret()
{
}
Turret Turret::getTurret()
{
return turret;
}
Turret::Turret(int en, int dir, int clk, void(*stepFunction)()):stepper2(en,dir,clk,stepFunction)
{
tso->getScale().tare();
tso->getScale().set_gain(128);
tso->getScale().set_scale(-3483.4);
}
void Turret::SeekBottleCenter()
{
Start();
while(irs->IRState()==1)
{
Serial.println("High");
Serial.println(irs->IRState());
}
while(irs->IRState()==0)
{
Serial.println("Low");
}
}
bool Turret::BottleCentered()
{
return turret.BottleCenterState;
}
void Turret::ClearFunction()
{
wt = tso->getScale().get_units();
while(wt>5)
{
Serial.println("Clearing");
wt = tso->getScale().get_units();
Rotate(20);
}
}
#endif
And above is the Turret.cpp file.
#ifndef IRSensor_cpp
#define IRSensor_cpp
#include "Arduino.h"
#include "IRSensor.h"
IRSensor i(5);
IRSensor::IRSensor(int pin)
{
IRSensorPin = pin;
pinMode(pin,INPUT);
}
int IRSensor::IRState()
{
return digitalRead(i.IRSensorPin);
}
#endif
And above is the IRSensor.cpp file. So essentially I press the go button declared in my main, that button calls monitor in the LoadBottleButton.cpp file, that method uses a turret point to get access to the Turret.cpp methods and a boolean named BottleCenterState. But the code only gets so far, it stops after printing "In" of the Serial.println("In Monitor") line. Why is that?
Don't count on the output to tell you where the error is. That serial print may have completed successfully and the message is buffered in an output stream waiting for a chance to be written to the serial port.
A much more likely cause of the crash is the line below the serial print.
Serial.println("In Monitor");
while(tPointer->getTurret().BottleCenterState==false)
tPointer is used and I don't see anywhere in the provided code it is assigned a valid, dereferencable pointer. Dereferencing an undefined pointer results in undefined behaviour, and in this case probably a crash. Even if it isn't the crash you are seeing, this is almost certainly wrong.
How to fix it?
From the code provided it doesn't look like tpointer needs to be a pointer at all.
Turret turret;
May be all you need. Allocating turret statically eliminates the possibility of pointer and memory management bugs and reduces the chance of leaks.
Otherwise,
Turret* tPointer = new Turret();
But this leaves you with the problem of how and when do you delete tPointer;.
Check that your string doesn't contain a NULL character. This will terminate the string abruptly.

Pantheios write to extenal file

I looked around and I couldn't find the answer to how exactly to do this. I am trying to use Pantheios for logging and I want to write to an external file (otherwise whats the point). I am following one of the examples provided but It doesn't seem to be making the log file anywhere. Here is the code:
Edit: Also pantheios_be_file_setFilePath is returning -4 (PANTHEIOS_INIT_RC_UNSPECIFIED_FAILURE) so thats.....not helpful
#include "stdafx.h"
#include <pantheios/pantheios.hpp>
#include <pantheios/implicit_link/core.h>
#include <pantheios/implicit_link/fe.simple.h>
#include <pantheios/implicit_link/be.WindowsConsole.h>
#include <pantheios/implicit_link/be.file.h>
#include <pantheios/frontends/fe.simple.h>
#include <pantheios/backends/bec.file.h>
#include <pantheios/inserters/args.hpp>
PANTHEIOS_EXTERN_C const PAN_CHAR_T PANTHEIOS_FE_PROCESS_IDENTITY[] = PANTHEIOS_LITERAL_STRING("LogTest");
int _tmain(int argc, _TCHAR* argv[])
{
try
{
pantheios_be_file_setFilePath(PANTHEIOS_LITERAL_STRING("testlogforme.log"), PANTHEIOS_BE_FILE_F_TRUNCATE, PANTHEIOS_BE_FILE_F_TRUNCATE, PANTHEIOS_BEID_ALL);
pantheios::log(pantheios::debug, "Entering main(", pantheios::args(argc,argv, pantheios::args::arg0FileOnly), ")");
pantheios::log_DEBUG("debug yo");
pantheios::log_INFORMATIONAL("informational fyi");
pantheios::log_NOTICE("notice me!");
pantheios::log_WARNING("warning!!");
pantheios::log_ERROR("error omg");
pantheios::log_CRITICAL("critical!!!");
pantheios::log_ALERT("alert mang");
pantheios::log_EMERGENCY("EMERGENCY!!!!!");
pantheios_be_file_setFilePath(NULL, PANTHEIOS_BEID_ALL);
system("pause");
return EXIT_SUCCESS;
}
catch(std::bad_alloc&)
{
pantheios::log_ALERT("out of memory");
}
catch(std::exception& x)
{
pantheios::log_CRITICAL("Exception: ", x);
}
catch(...)
{
pantheios::puts(pantheios::emergency, "Unexpected unknown error");
}
return EXIT_FAILURE;
}
Maybe I'm not calling a method or maybe its not being saved to a good location?
It turns out that some of the examples out there for pantheios are incorrect. You DO need to call pantheios_init() even if you are in C++. Here Is the example I got to work after deleting all my code and implementing an example that works.
// Headers for main()
#include <pantheios/pantheios.hpp>
#include <pantheios/backends/bec.file.h>
// Headers for implicit linking
#include <pantheios/implicit_link/core.h>
#include <pantheios/implicit_link/fe.simple.h>
#include <pantheios/implicit_link/be.file.h>
PANTHEIOS_EXTERN_C const char PANTHEIOS_FE_PROCESS_IDENTITY[] = "testLOL";
int main()
{
if(pantheios::pantheios_init() < 0)
{
return 1;
}
pantheios::log_NOTICE("log-1"); // save until log file set
pantheios_be_file_setFilePath("mylogfile.log"); // sets log file; write "log-1" stmt
pantheios::log_NOTICE("log-2"); // write "log-2" stmt
pantheios_be_file_setFilePath(NULL); // close "mylogfile"
pantheios::log_NOTICE("log-3"); // save until log file set
pantheios_be_file_setFilePath("mylogfile2.log"); // sets log file; write "log-3" stmt
pantheios::log_NOTICE("log-4"); // write "log-4" stmt
//system("pause");
return 0;
} // closes "mylogfile2" during program closedown
I found the example on a different post on stack overflow but like I said, the built in examples do not work.

return an array from a function member of a class in C++

I'm using ROS and OpenCV in C++ environment in order to acquire a video (gray-scale) from a ROS node, convert the data through cv_bridge (in order to elaborate it through OpenCV), extract some data and publish them on a topic as ROS messages.
My problem is that I don't know how to send the array frame to the main function in order to elaborate it! I cannot elaborate out of it, because I need to distinguish between different data of different frames.
This is my code:
#include <ros/ros.h>
#include <image_transport/image_transport.h>
#include <cv_bridge/cv_bridge.h>
#include <sensor_msgs/image_encodings.h>
#include <opencv2/imgproc/imgproc.hpp>
#include <opencv2/highgui/highgui.hpp>
#include <vector>
#include "rd_ctrl/proc_data.h"
#include <cv.h>
using namespace std;
namespace enc = sensor_msgs::image_encodings;
rd_ctrl::proc_data points;
ros::Publisher data_pub_;
static const char WINDOW[] = "Image window";
class ImageConverter
{
ros::NodeHandle nh_;
image_transport::ImageTransport it_;
image_transport::Subscriber image_sub_;
image_transport::Publisher image_pub_;
public:
ImageConverter()
: it_(nh_)
{
image_pub_ = it_.advertise("out", 1);
image_sub_ = it_.subscribe("/vrep/visionSensorData", 1, &ImageConverter::imageCb, this);
cv::namedWindow(WINDOW);
}
~ImageConverter()
{
cv::destroyWindow(WINDOW);
}
void imageCb(const sensor_msgs::ImageConstPtr& msg)
{
cv_bridge::CvImagePtr cv_ptr;
try
{
cv_ptr = cv_bridge::toCvCopy(msg, enc::BGR8);
}
catch (cv_bridge::Exception& e)
{
ROS_ERROR("cv_bridge exception: %s", e.what());
return;
}
CvMat frame= cv_ptr->image; //definition of "frame"
cvSmooth(&frame, &frame, CV_MEDIAN);
cvThreshold(&frame, &frame,200, 255,CV_THRESH_BINARY);
cv::imshow(WINDOW, cv_ptr->image);
cv::waitKey(3);
image_pub_.publish(cv_ptr->toImageMsg());
}
};
int main(int argc, char** argv)
{
ros::init(argc, argv, "image_proc");
ImageConverter ic;
ros::NodeHandle n;
//....elaboration of "frame" and production of the data "points"
data_pub_.publish(points);
data_pub_ = n.advertise<rd_ctrl::proc_data>("/data_im", 1);
ros::spin();
return 0;
}
I hope that the question is clear enough. Can you help me please?
Now if I understand you correctly you want to call imageCb and have the frame it creates passed back to main. If that is indeed the case then you can modify imageCb as follows:
void imageCb(const sensor_msgs::ImageConstPtr& msg, cv::Mat frame )
You will need to create the frame in main and pass it imageCb:
cv::Mat frame ;
ic.imageCb( ..., frame ) ;
This will use the copy constructor, it will just copy the header and use a pointer to the actual data, so it won't be very expensive.
This previous thread has a much more detailed elaboration on cv::Mat copy constructor.