I'm following some tutorials by Bartosz Milewski here which I find very useful.
However, as the author uses the just::thread implementation of the C++11 threading standard (which I don't yet have), I have decided to go with boost threads for now as the author of the tutorial says its trivial to do so. This seems to be the case for the first three tutorials in the series but I bumped into some problems with the fourth. Here is my code:
#include <iostream>
#include <cassert>
#include <boost\thread.hpp>
#include <boost\thread\future.hpp>
void thFun(boost::promise<std::string> & prms)
{
std::string str("Hi from future!");
prms.set_value(str);
}
int main()
{
boost::promise<std::string> prms;
boost::unique_future<std::string> fut = prms.get_future();
boost::thread th(&thFun, std::move(prms)); // error C2248: 'boost::promise<R>::promise' : cannot access private member declared in class 'boost::promise<R>'
std::cout << "Hi from main!";
std::string str = fut.get();
std::cout << str << std::endl;
th.join();
return 0;
}
The following line seems to raise an issue that I don't understand:
boost::thread th(&thFun, std::move(prms));
where the compiler complains:
error C2248: 'boost::promise::promise' : cannot access private
member declared in class 'boost::promise'
Can anyone suggest what the problem might be?
thanks in advance!
boost::thread uses boost::bind to handle a thread function with additional arguments, which requires that they are copyable. You could pass the promise by pointer or reference (using e.g. boost::ref), but that requires that the object outlives the thread. In this example it is OK, but for a detached thread, or one which outlives the function that started it, this would prevent the use of boost::promise objects on the stack.
Related
I've been porting some c++ app from Visual Studio 2013 to Visual Studio 2017. Aside from the plethora of new warnings that I had to fix, the compilation and linking went okay.
However, when running the app, it 'stalled' when trying to re-enter the constructor of a singleton (when successive function calls form a loop back to the constructor). It seems that this behaviour was okay in VS2013, but is no longer valid in VS2017. There is no error message.
I'm aware of all the bad things related to singletons, and that there should at least not be loops. The question is not there.
Is there a way to tell the VS2017 compiler that I'd like to shoot myself in the foot, and allow the same behaviour that was there in VS2013?
I don't have access to the code that causes this behaviour because it comes from a third-party library, this is why I can't 'just fix it', unfortunately.
Here is an example which works in VS2013, but doesn't work in VS2017:
main.cpp
#include "Singleton.h";
int
main( void )
{
std::cout << "let's do this!" << std::endl;
int two = Singleton::GetReference().getTwo();
std::cout << "ok" << std::endl;
return 0;
}
Singleton.h
#pragma once
class Stuff;
class Singleton
{
public:
static Singleton& GetReference();
int getTwo() { return 2; }
private:
Singleton();
Stuff* stuff;
};
Singleton.cpp
#include "Singleton.h"
#include "Stuff.h"
Singleton&
Singleton::GetReference() {
static Singleton theInstance;
return theInstance;
}
Singleton::Singleton()
{
stuff = new Stuff();
}
Stuff.h
#pragma once
class Stuff
{
public:
Stuff();
private:
int two;
};
Stuff.cpp
#include "Stuff.h"
#include "Singleton.h"
Stuff::Stuff()
{
two = Singleton::GetReference().getTwo();
}
In the code above, when step-by-step debugging, the first time we get on the line static Singleton theInstance; will work as expected, but the second time, a F11 will go to the file thread_safe_statics.cpp, into the method extern "C" void __cdecl _Init_thread_header(int* const pOnce). A Shift+F11 will exit the method and the program will wait indefinitely at the line specified (observed when pausing the program from the debugger).
PS
This issue probably occurs in Visual Studio 2015 too, as the documentation linked from the accepted answer mentions VS2015.
/Zc:threadSafeInit-
The general "Conformance" page is MSDN: Conformance, which details which new features you can disable.
I needed the code for sizedDealloc, where my new compiler was creating a sized new operator for a library which broke older compiled expectations.
As this is a compile flag, at least some of the code would be in your control, and you should be able to unravel the beast.
The constructor Stuff::Stuff is calling a function on an incompletely constructed object.
That would create "Undefined behavior". If the value "2" is not set till the end of the constructor (for example).
Probably the Singleton needs to be split into 2, one which delivers the early static data (e.g. 2).
The second which delivers the held object Stuff. Stuff would only rely on the first, which would break the deadlock.
Alternatively, a second constructor to Stuff which told it which object to use, and was called from the Singleton::Singleton
The MSDN article to disable "Magic Statics" MSDN : disable threadsafe static initialization
I'm trying to use Pleora SDK for creating a application to load images from a thermal camera.
So my first attempt is to find available devices in the network, however I'm facing a weird behavior in C++ that I really have no reasonable explanation: the code flow jumps to somewere else than the main function on the declaration of "PvSystem lSystem" even when it is not being called.
To aid my explanation, here is the code:
#include <iostream>
#include <PvSystem.h>
#include <PvInterface.h>
#include <PvDevice.h>
int DeviceFinding()
{
PvSystem lSystem;
return 0;
}
int main()
{
std::cout << "Application start" << std::endl;
//DeviceFinding();
return 0;
}
This code, when run on Ubuntu 16.04 64bits with the following build line:
g++ weird.cpp -g3 -o WeirdTest -I/opt/pleora/ebus_sdk/Ubuntu-14.04-x86_64/include -L/opt/pleora/ebus_sdk/Ubuntu-14.04-x86_64/lib -lPvBase -lPvBuffer -lPvStream -lPvDevice -lPvGenICam
outputs:
Error: GENICAM_ROOT_V2_4 is not set.
However, if I comment the line with "PvSystem lSystem",
#include <iostream>
#include <PvSystem.h>
#include <PvInterface.h>
#include <PvDevice.h>
int DeviceFinding()
{
// PvSystem lSystem;
return 0;
}
int main()
{
std::cout << "Application start" << std::endl;
//DeviceFinding();
return 0;
}
the application prints what is expected:
Application start
I really have no idea of what is going on. Can someone help me understanding this?
Intializations of global variables are invoked before main starts.
I dont know the Pleora SDK, but a possible explanation of the pattern is that PvSystem references some global object that needs to be constructed (or a global variable initialized through some function) before main starts, the error occurs in that constructor.
When that global object or variable is not referenced anywhere (when you comment the line PvSystem lSystem;) the linker dropped that global object from the linking and no constructor or initializer was called. That is because the linker is allowed to drop unreferenced globals from a library.
On the other hand, when you activate that line, the linker instantiated the global object (or variable) because it is referenced somewhere in PvSystem, and it invoked its constructor (or initializer) before main. That initializer has detected some error in the environment so it exited the application or threw an exception.
Another possibility is, as in #SamVarshavchik 's comment, you have yourself in your code some constructors (for global objects) invoked before main and a bug in those constructors provoked an undefined behavior.
Good evening everyone !
I am trying to code a multi-threaded application in C++ with Microsoft Visual Studio Express 2012.
The idea us that the "main" function call a thread which will run "forever", with the task of updating an object.
This is the main :
#include "stdafx.h"
#include <iostream>
#include <windows.h>
#include <cstdlib>
#include <thread>
#include <iostream>//debug only
#include <fstream> //debug only
#include "dataCollectorFTL.h"
int _tmain(int argc, _TCHAR* argv[])
{
dataCollectorFTL dataCollector1;
//Launch thread which will run forever and get the data flows
dataCollector1.runDataCollector();
while(true){
//application running
}
return 0;
}
This is the ".h" of the class
#ifndef DATACOLLECTORFTL_H_INCLUDED
#define DATACOLLECTORFTL_H_INCLUDED
#include <thread>
class dataCollectorFTL {
public:
void runDataCollector();
void getData();
//constructor, destructor
dataCollectorFTL();
~dataCollectorFTL();
private:
HANDLE hProcess;
std::thread dataCollectorThread;
};
#endif // DATACOLLECTORFTL_H_INCLUDED
And finally the ".cpp"
#include "stdafx.h"
#include <iostream>
#include <windows.h>
#include <thread>
#include "dataCollectorFTL.h"
void dataCollectorFTL::runDataCollector(){
//lauch a non-local thread
dataCollectorThread = std::thread(&dataCollectorFTL::getData, this);
}
void dataCollectorFTL::getData(){
//some stuff
}
dataCollectorFTL::dataCollectorFTL(){
//some stuff
}
dataCollectorFTL::~dataCollectorFTL(){
dataCollectorThread.join();
}
The problem is that when I run it, it gaves me this two errors :
Error 1 error C2248: 'std::thread::operator =' : cannot access private member declared in class 'std::thread' c:\users\damien\documents\visual studio 2012\projects\recherche\recherche\datacollectorftl.h 233 1 Recherche
Error 4 error C2248: 'std::thread::thread' : cannot access private member declared in class 'std::thread' c:\users\damien\documents\visual studio 2012\projects\recherche\recherche\datacollectorftl.h 233 1 Recherche
To save time, I can tell you that :
include in the .h doesn't change anything
The content of the runDataCollector methods doesn't change anything. Even if it is empty I still got the problem
std::thread dataCollectorThread can be public or private, it doesn't change anything
If I don't declare as a member of the class, I have a crash of the program because I don't join() the thread in runDataCollector(). And I don't want to join it, has getData() is a while(true) function where it gets data from another soft.
Thank you very much for the time you spent reading this, and thank you again for any help.
I understand that it was some time ago, but I bumped into the problem with same symptoms, and was able to solve it since my compilator (VC110 shipped with VS2012) was a little bit more verbose about what's the problem, so maybe it will help somebody.
I wanted to use this struct:
struct WorkerThreadContext
{
std::thread worker;
... some other attributes ...
}
in a std::vector. Build resulted in error message:
d:\code\testroom\t2\t2\t2.cpp(16): error C2248:
'std::thread::thread' : cannot access private member declared in class 'std::thread'
c:\program files (x86)\microsoft visual studio 11.0\vc\include\thread(73) : see declaration of 'std::thread::thread'
c:\program files (x86)\microsoft visual studio 11.0\vc\include\thread(32) : see declaration of 'std::thread'
This diagnostic occurred in the compiler generated function WorkerThreadContext::WorkerThreadContext(const WorkerThreadContext &)'
Key part is the last sentence - it seems that compiler has a problem to generate implicit copy constructor for my struct, so I changed it to:
struct WorkerThreadContext
{
std::thread worker;
... other attributes ...
WorkerThreadContext() {}
// added explicit copy constructor
WorkerThreadContext(const WorkerThreadContext&) {}
};
and was able to compile the code.
Edit: I almost forget. The reason why the compiler has a problem with this is, that std::thread objects cannot be copied (std::thread::operator=) so the compiler has a problem to construct implicit copy constructor, because it doesn't know how to copy the 'std::thread' object. Which also means, that if you put there explicit copy constructor as the one I wrote, your members (including the 'std::thread' one become invalid). You may (and you should) of course initialize the rest of the struct, however std::thread will remain uninitialized, because you cannot copy it.
When you pass a function in to the std::thread constructor, it needs to be callable from file-scope. In other words, if it's a member function, that function needs to be static. You can still pass in this - just tell the function to expect it.
In other words:
Add the following to the class declaration:
private:
void getData(); // Moved from public!
static void myGetData(DataCollectorFTL *ftl);
Write myGetData:
void DataCollectorFTL::myGetData(DataCollectorFTL *ftl) {
ftl->getData();
} // DataCollectorFLT::myGetData(ftl)
Change the call to std::thread()
//lauch a non-local thread
dataCollectorThread = std::thread(&myGetData, this);
This question already has answers here:
Start thread with member function
(5 answers)
Closed 7 years ago.
Good afternoon,
I've been attempting to create a handful of threads to execute an update loop on some data, but when I attempt to call std::thread newThread(updateLoop), I get a generic compiler error for:
"No instance of constructor 'std::thread::thread' matches the argument list,"
and a MS VC++ 2015 error C3867:
"'projectileHandeler::updateLoop': non-standard syntax; use '&' to create a pointer to member"
When I attempt to follow the recommendation in C3867, changing the threading call to std::thread newThread(&updateLoop) the compiler throws MS VC++ C2276:
"'&': illegal operation on bound member function expression."
After reading the compiler error resources and trying variations such as std::thread newThread(this->updateLoop), std::thread newThread(*updateLoop), and std::thread newThread(*&updateLoop) [I was getting desperate then... I knew that last one wasn't going to work... ], I still get various errors relating to either an improper reference or my call the std::thread not matching the any overloads.
Could anyone please shed some light on my mistakes, please?
Of course, the code:
ProjectHandeler.cpp:
NB: The standard library thread and vector headers are included in stdafx.h
#include "stdafx.h"
#include "DataTypes.h"
#include "ProjectHandeler.h"
projectileHandeler::projectileHandeler(projectile* inputList[], int inputCount) {
for (int i = 0; i < inputCount; i++) {
projectileList.push_back(*inputList[i]);
}
//Create 1 thread for each 10 projectiles.
for (unsigned int i = 0; i < projectileList.size(); i++) {
std::thread thread(updateLoop);
thread.detach();
}
}
void projectileHandeler::updateLoop() {
//Do stuff
}
ProjectHandeler.h:
#pragma once
#ifndef PROJECTILE_H
#define PROJECTILE_H
#include "stdafx.h"
#include "DataTypes.h"
#endif
class projectileHandeler {
private:
std::vector<projectile> projectileList;
void updateLoop();
public:
projectileHandeler(projectile* inputList[], int inputCount);
~projectileHandeler();
projectile* getProjectilePointerFromId(unsigned int id);
//Make the NPC and Player handeler friend classes
};
Solution found... Although I still can't make the original version work, studying the post suggested by Niall had an obscure mention to using lambdas to preform the threading, which bypasses the need for member function references.
Therefore std::thread newThread(updateLoop); becomes std::thread([this] { updateLoop(); });
The later version also has the benefit of starting the thread anonymously,allowing the loop to execute with out having to rename anything.
That said, I would still appreciate an explanation to why the original code doesn't compile. After reading through it, I couldn't find an answer for the specific case here in the suggested duplicate post.
the following program give some strange compile/run-time behavior when compiled with Visual Studio 2013:
#include "stdafx.h"
#include <thread>
#include <chrono>
#include <iostream>
int main()
{
{//works
std::thread([](){
std::cout << " thread running1\n";
});
}
{//compile but synstax error exist
auto func = [](){
std::cout << " thread running2\n";
};
std::thread(fun); //fun is not defined
}
{//compile, see next block for mystery compile error
auto func = [](){
std::cout << " thread running2\n";
};
std::thread tmp(func);
}
{//does not compile and don't know why
auto func = [](){
std::cout << " thread running2\n";
};
std::thread(func); //error C2371: 'func' : redefinition; different basic types
}
return 0;
}
When this program work, there may crash as there is race condition between the thread. The main thread may end before the other threads.
Does anybody know why the second block and last block does not work?
{//compile but synstax error exist
auto func = [](){
std::cout << " thread running2\n";
};
std::thread(fun); //fun is not defined
}
There's no syntax error here, std::thread(fun) default constructs an std::thread object named fun.
The error in the last block is because of the same reason
std::thread(func); //error C2371: 'func' : redefinition; different basic types
You're trying to default construct an std::thread object named func above and that's an error because a lambda of the same name already exists in the same scope. To pass the lambda to the thread constructor use braces instead
std::thread{func};
Now, after you've made these changes your code will compile but will fail at runtime because the thread objects in blocks 1, 3 & 4 are all going to call std::terminate (of course, your program terminates when the first thread object calls std::terminate so the other two doing that is a moot point).
The reason that happens is that you have joinable threads in all 3 blocks and if the destructor of such a thread object runs, std::terminate will be called. To avoid that you must call thread::join (you could also call thread::detach but don't do that).
For instance
{//works
std::thread([](){
std::cout << " thread running1\n";
}).join();
}
Live demo