trying Multithreading in a class (c++11) [duplicate] - c++

This question already has answers here:
Start thread with member function
(5 answers)
Closed 8 years ago.
I'm trying to make a class with a method that calls other method (that is in the same class) multiple times using multithreading. The code is something like this:
#include <iostream>
#include <thread>
using namespace std;
class ThreadedMatcher
{
float Match()
{
thread t[5];
//5 is just as an aleatory number
//The error doesn't change if I use a pointer (like thread *t;)
for (int i = 0; i < num_jobs; i++)
{
t[i](partialMatch,i);
}
}
void partialMatch(int i){
//Whathever I put in here doesn't change the error
}
}
(this code is written in "ThreadedMatcher.h")
When I compile this, the next two errors appear:
error c3867: 'ThreadedMatcher::partialMatch': function call missing argument list; use '&ThreadedMatcher::partialMatch' to create a pointer to member
error c2064: term does not evaluate to a function taking 2 arguments
(these two errors refers to the part inside the for bucle)
If I follow the advise in the first error, the second error stays there anyway.
Could anyone tell me how to solve this? I'm using visual studio 2012 (c++11), in windows 8.
Thank you for any help you can provide.
PS: Sorry for my bad english, I did the best I could

To reference a function in a class, you must reference the class in which the function resides.
change your thread execution to pass by reference.
This SO question
Explains it nicely
From that question
void Test::runMultiThread()
{
std::thread t1(&Test::calculate, this, 0, 10);
std::thread t2(&Test::calculate, this, 11, 20);
t1.join();
t2.join();
}

Related

What is Wrong with my Code in calling function in main?

#include <iostream>
#include <vector>
using namespace std;
int main()
{
vector<int> big_vector = {5,12,4,6,7,8,9,9,31,1,1,5,76,78,8};
vector<int> a = sub(big_vector);
cout<<a.size();
return 0;
}
vector<int> sub(vector<int> big_vector){
return {big_vector.begin() + 7, big_vector.end() - 2};
}
I get this error and do not know why
main.cpp:18:21: error: ‘sub’ was not declared in this scope
debugging and running different test
In C++ all objects must be declared before they are used.
vector<int> a = sub(big_vector);
Your reliable compiler reads this, and it has absolutely no clue, whatsoever, what this mysterious sub function is all about.
Human eyeballs that are owned by a carbon-based life form can easily see this function, later in the file. But your compiler is a beast of logic. It hasn't read that far ahead, into the source file. That's why, in C++, in this situation the function must be declared:
vector<int> sub(vector<int>);
Put this before the main function. The compiler reads this first, and learns all about this amazing function called sub(), which has one vector<int> parameter, and returns a vector<int> itself. So when it reads the contents of main(), which calls this function, it knows exactly what it's all about, and can proceed further.
Or, you can simply put the entire sub() function before the main() function. That'll work, too.

boost::bind member function as argument inside its own member function

I am following a tutorial (https://www.gamedev.net/blogs/entry/2249317-a-guide-to-getting-started-with-boostasio/) for boost asio.
Now I want to convert some of the aspects of this tutorial to a class, to learn more about what actually goes on within each part of the code. So I am trying to boost bind this:
class LDserver
{
public:
void workerThread(boost::shared_ptr<boost::asio::io_service> io_service)
{
io_service->run();
}
void createThreads()
{
this->worker_threads.create_thread(boost::bind(&LDserver::workerThread, this->io_service));
}
~LDserver() = default;
boost::thread_group worker_threads;
boost::shared_ptr<boost::asio::io_service> io_service = boost::make_shared<boost::asio::io_service>();
boost::shared_ptr<boost::asio::io_service::work> work = boost::make_shared<boost::asio::io_service::work>(*this->io_service);
boost::asio::io_service::strand strand = boost::asio::io_service::strand(*this->io_service);
};
Following the documentation, it states that this should be the correct syntax AS its own, so not as an argument. But instead I am greeted with an error message coming from the boost::bind library.
Severity Code Description Project File Line Suppression State
Error C2440 'return': cannot convert from 'R (__cdecl &)' to 'R' LockManager C:\Boost\boost_1_75_0\boost_1_75_0\boost\bind\bind.hpp 227
It work fine if I follow the documentation and put it in the mainloop, it even takes the member variable fine as an argument:
LDserver s1;
for (int i = 0; i <= 2; i++)
{
s1.worker_threads.create_thread(boost::bind(&workerThread, s1.io_service));
}
And by commenting out I am 100% sure because it doesnt take my way of syntaxing the worketThread() member function as the correct one, however after spending 2 days of trying and finding the answer, I hope someone here could enlighten me.
The problem is that the thread function isn't static, so it needs an argument for this (LDServer*). Or you can make it static:
static void workerThread(boost::shared_ptr<ba::io_service> io_service) {
io_service->run();
}
void createThreads() {
worker_threads.create_thread(
boost::bind(&LDserver::workerThread, io_service));
}
However, all the rampant dynamic allocation, shared ownership and manual threading, as well as the boost bind/shared_ptr instead of standard library are all code smells. If you're using a VeryOldOrBadBook(TM) to learn this from, please compare:
#include <boost/asio.hpp>
namespace net = boost::asio;
class LDserver : public std::enable_shared_from_this<LDserver> {
using executor_type = net::thread_pool::executor_type;
net::thread_pool _ctx{1}; // one thread please
net::strand<executor_type> _strand{_ctx.get_executor()};
public:
~LDserver() {
_ctx.join(); // don't forget to join your threads anyway
}
};

c++ thread function pointer implementation returns error invalid use of non-static member function [duplicate]

This question already has answers here:
Start thread with member function
(5 answers)
Closed 3 years ago.
I've been trying to get the hang of threading for a while, but it seems no matter how many examples or similar SOflow questions I look at, nothing is enlightening me to the answer. I need to call a member function of a class as a thread from the constructor of the class.
I've tried various different changes (very few of which I've actually understood the purpose of, since I'm new to threading - sorry guys!) such as setting the target function to static (which caused a massive number of errors to occur in it's place - even though it seemed to resolve the invalid use).
The basic of what I've got so far is:
class VideoController
{
VideoController()
{
//initialise everything else
std::thread t(VideoController::Heartbeat)//originally: t(Heartbeat);
// //and have tried: (Heartbeat, NULL);
}
void Heartbeat() //tried: static void Heartbeat() && void Heartbeat(void)
{
while(true) //(why threading is essential)
{
//carry out function
}
}
}
The error that this is giving me is:
VideoController.cpp: In constructor 'VideoController::VideoController(std::__cxx11::string, std::__cxx11::string, std::__cxx11::string)':
VideoController.cpp:115:49: error: invalid use of non-static member function 'void VideoController::Heartbeat()'
std::thread t(Heartbeat);
.......................^
If someone could learn me a thing or two about exactly why this isn't working for me, it'd be greatly appreciated!
class A
{
void threadfunc() { ... }
void foo()
{
std::thread t(&A::threadfunc,this);
...
}
};
Well creating a thread using a member function, you must also pass this (as all non static member functions take a hidden pointer to the class as their first argument).

c++ 11 - passing member function to thread gives: no overloaded function takes 2 arguments

From what I have looked up, my syntax is correct but my compiler (VS2015) is complaining. Note, I'm using namespace ee with the class Network. Here's the code
//code that doens't work
thread clientThread(&ee::Network::clientRun, new ee::Network);
*note: in the real code I'm not calling new as an argument, I did it here to shorten code.
I've tested the functions and they work, I just can't get them to work using thread. Here is their signatures.
void serverRun();
void clientRun();
void clientRun(string ip);
My errors are:
Error C2661 'std::thread::thread': no overloaded function takes 2 arguments
abc no instance of constructor "std::thread::thread" matches the argument list
Does anyone have any insight as to what might be happening in this situation?
Ben's suggestion fixed my problem, but I'm not sure why.
The problem is with the first argument &ee::Network::clientRun. clientRun has 2 overloads, but at the point of template deduction (to deduce the types of the arguments to std::thread::thread<>) the compiler is not yet in a position to distinguish which of the overloads is more valid.
Ben's solution worked because the cast prior to the call has done the compilers' work for it - by specifying the type of Network::clientRun to be void (ee::Network*)(void) rather than the equally valid void (ee::Network*)(string).
Some examples:
#include <thread>
#include <string>
struct Network
{
void clientRun();
void clientRun(std::string);
};
int main()
{
// not ok...
// std::thread clientThread(&Network::clientRun, new Network);
// ok - tells the compiler which overload
auto member_function = static_cast<void (Network::*)()>(&Network::clientRun);
std::thread clientThreadA(member_function, new Network);
// also ok
using call_type = void (Network::*)();
std::thread clientThreadB(call_type(&Network::clientRun), new Network);
}

C++ Changing the values of members of a const struct [duplicate]

This question already has answers here:
C/C++ changing the value of a const
(18 answers)
Closed 8 years ago.
I have a struct which is defined in types.h with the following code:
struct data_Variant {
FlightPlanSteeringDataRecord steeringData;
FlightPlanType flightPlan : 8;
MinitoteLegDataType legDataType : 8; // discriminent, either current or amplified
unsigned spare : 16;
union {
// currentLeg =>
CurrentLegDataRecord currentLegData;
// amplifiedLeg =>
AmplifiedLegDataRecord amplifiedLegData;
} u;
};
I am then trying to pass an instance of that struct as a parameter to a function in a C++ source file called dialogue.cpp:
void dialogue::update( const types::data_Variant& perfData){
...
}
I now want to change the value of some of the members of that struct inside this update() function. However, if I try doing this as I usually would, i.e.
perfData.etaValid = true;
I get a compile error which says: "C2166: l-value specifies const object". As I understand, this is because perfData has been declared as a constant variable. Am I correct in thinking this?
Since I didn't write this part of the code, but only want to use it to update the value displayed on the GUI, I don't really want to change the perfData variable by removing the const keyword, in case I break something else. Is there any way to change the value of a variable that has been declared as const?
I have tried declaring the same struct variable in another part of the code, without using the const keyword, to see if I can change the values of some of its members there... i.e. in Interface.cpp, I have added the following code to a function called sendData():
types::data_Variant& perfData;
perfData.steering.etaValid = true;
perfData.steering.ttgValid = true;
However, I now get the following compile errors on these lines:
error C2653: 'types' is not a class or namespace name
error C2065: data_Variant: undeclared identifier
error C2065: 'perfData': undeclared identifier
error C2228: left of '.steering' must have class/ struct/ union
Is there a way of updating the values of this struct? If so, how should I do it, and what am I doing wrong here?
I have added the following function to the dialogue.cpp source file, as suggested in the answer:
void dialogue::setFPTTGandETAValidityTrue(
FlightPlanMinitoteTypes::FlightPlanMinitoteData_Variant& perfData)
{
SESL_FUNCTION_BEGIN(setFPTTGandETAValidityTrue)
perfData.steeringData.fpETAValid = true;
perfData.steeringData.fpTTGValid = true;
SESL_FUNCTION_END()
}
You could add a wrapper for yourself.
void myupdate(dialogue& dia, types::data_Variant& perfData)
{
perfData.etaValid = true;
dia.update(perfData);
}
Then call myupdate() instead of dialogue::update().
You declare
void dialogue::update( const types::data_Variant& perfData){
...
}
that const is a declaration of you saying: "I won't modify the referenced object in this function". If you want to modify it in dialogue::update you have to remove the const keyword. Wrapping is not a solution, in my opinion, makes the code harder to maintain. Also I vote against remove const with const_cast.
The correct solution is to remove const from method declaration if you want to modify the referenced object inside that function.