I'm trying to creating a logging class where the call to write a log is static. Now, due to performance requirements I'm want to perform the actual logging in a separate thread. Since the function to write to a log is static, I think the thread also needs to be static, which is also tied to another static member function that performs the actual writing of the log. I tried coding it but somehow it hangs during the initialization of the static thread. The code sample that duplicates the behavior is below:
"Logger.h"
#ifndef LOGGER_H
#define LOGGER_H
#include <condition_variable>
#include <mutex>
#include <queue>
#include <string>
#include <thread>
#include <vector>
#define LIBRARY_EXPORTS
#ifdef LIBRARY_EXPORTS // inside DLL
#define LIBRARY_API __declspec(dllexport)
#else // outside DLL
#define LIBRARY_API __declspec(dllimport)
#endif
using namespace std;
namespace Company { namespace Logging {
class LIBRARY_API Logger
{
public:
~Logger();
void static Write(string message, vector<string> categories = vector<string>());
private:
Logger();
Logger(Logger const&) {}
void operator=(Logger const&) {}
static thread processLogEntriesThread;
static void ProcessLogEntries();
};
}}
#endif
"Logger.cpp"
#include "Logger.h"
#include <iostream>
using namespace std;
namespace Company { namespace Logging {
thread Logger::processLogEntriesThread = thread(&Logger::ProcessLogEntries);
Logger::Logger()
{
}
Logger::~Logger()
{
Logger::processLogEntriesThread.join();
}
void Logger::Write(string message, vector<string> categories)
{
cout << message << endl;
}
void Logger::ProcessLogEntries()
{
}
}}
One odd behavior that I found is that the hanging part only happens when the class packaged in a DLL. If I use the class files directly into the console EXE project it seems to be working.
So basically my problem is the hanging part and if I'm doing things correctly.
Thanks in advance...
you can use my logger library => https://github.com/PraGitHub/Prapository/tree/master/C_Cpp/Logger
If this post is found irrelevant, please pardon me.
the hanging part only happens when the class packaged in a DLL
See Dynamic-Link Library Best Practices for full details why it hangs:
You should never perform the following tasks from within DllMain:
Call CreateThread. Creating a thread can work if you do not synchronize with other threads, but it is risky.
The solution is provide an initialization function/object for your logger library that the user must call explicitly in main, rather than having a global thread object initialized before main is entered. This function should create the thread.
Or create the thread on the first logging call using std::call_once. However, this involves an extra conditional check on each logging call. This check may be cheap but it is not free.
I can not see any usage of the logger thread. Having a thread as member in a class did not mean that all member functions will run in the created thread. The destructor of logger will never called, while you have no logger instance. iostream is not thread safe!
What you have to do:
Create some kind of storage to collect the logging infos. This instance must be thread safe!
Push messages from the outside world into this instance. The instance itself must have a own thread which reads from the storage and put the data to the output. This must be done also in a thread safe manner because reading and writing comes from different threads!
Related
I'm looking into ways to prevent unnecessary clutter in setup code in main() as well as various other places. I often have tons of setup code that registers itself with some factory. A standard example is e.g. handlers for various file types.
To avoid having to write this code and instead just make handlers magically work if linked into the application, I figured I could replace the code by something like the following:
test.cc:
int main() {
return 0;
}
loader.h:
#ifndef LOADER_H_
#define LOADER_H_
#include <functional>
namespace loader {
class Loader {
public:
Loader(std::function<void()> f);
};
} // namespace loader
#define REGISTER_HANDLER(name, f) \
namespace { \
::loader::Loader _macro_internal_ ## name(f); \
}
#endif // LOADER_H_
loader.cc:
#include "loader.h"
#include <iostream>
namespace loader {
Loader::Loader(std::function<void()> f) { f(); }
} // namespace loader
a.cc:
#include <iostream>
#include "loader.h"
REGISTER_HANDLER(a, []() {
std::cout << "hello from a" << std::endl;
})
The idea here is that a.cc would in a real application e.g. call some method where it registers it self as a handler for a certain file type. Compiling the code with c++ -std=c++11 test.cc loader.cc a.cc creates a binary that prints "hello from a" while c++ -std=c++11 test.cc loader.cc stays silent.
I'm wondering if there's something subtle that I might need to be careful with? For example, if someone creates complex objects in the lambda that is run here, I assume weird things can happen during cleanup for example in a multithreaded application?
You wrote:
... unnecessary clutter in setup code in main() ...
int main() {
return 0;
}
This is not preventing unnecessary clutter. This is hiding your initializations. They still occur, but now you have to chase after them. That's really not the way to do it. Also, it will force the use of a lot of global state - in many independent global variables, most probably - which is also a bad thing. Instead, consider writing something like:
class my_app_state { /* ... */ };
my_app_state initialize(/* perhaps with argc and argv here? */) {
//
// Your "unnecessary" clutter goes here...
//
return whatever;
}
int main() {
auto app_state = initialize();
//
// do stuff involving the app_state...
//
}
and don't try to "game" the program loader.
This approach is not guaranteed to work:
[basic.start.dynamic]/4 It is implementation-defined whether the dynamic initialization of a non-local non-inline variable with static storage duration is sequenced before the first statement of main or is deferred. If it is deferred, it strongly happens before any non-initialization odr-use of any non-inline function or non-inline variable defined in the same translation unit as the variable to be initialized.
Thus, the initialization of _macro_internal_a may be deferred until something in a.cc is used. And since nothing in a.cc is in fact used, the initialization may not be performed at all.
In practice, linkers tend to discard object files that do not appear to be referenced by anything in the program (especially when those files come from libraries).
One of my project for Linux uses a lot of shared libraries which are connected with dlopen/dlsym/dlclose to gain modularity. For thread-safety reason, I need to put global variable (boost::mutex) in one of shared library. Obviously, boost::mutex has non-trivial destructor. (it can even abort(3) the program).
I understand that using global variable that are not trivially destructible is bad idea and some guidelines are explicitly forbid to do such things, but I really need global mutex for the module.
After adding global boost::mutex variable, it crashes on program exit. (boost::mutex::lock() throws because of EINVAL of pthread_mutex_lock) I assume that the shared libary called after main, but, that mutex is already destroyed. (static destruction order fiasco things, I assume.)
Unfortunately, this program is quite complicated and I need a workaround to do my job on time.
After digging ctor/dtor things, I found that this code works.
#include <boost/aligned_storage.hpp>
#include <boost/thread/lock_guard.hpp>
#include <boost/thread/mutex.hpp>
#include <boost/type_traits/alignment_of.hpp>
boost::aligned_storage<sizeof(boost::mutex), boost::alignment_of<boost::mutex>::value> gMutexStorage;
boost::mutex* gMutex = NULL;
__attribute__ ((constructor))
void MyModuleInit()
{
gMutex = new(reinterpret_cast<boost::mutex*>(gMutexStorage.address())) boost::mutex();
}
__attribute__ ((destructor))
void MyModuleUnInit()
{
gMutex->~mutex();
gMutex = NULL;
}
// global mutex use
extern "C" __attribute__ ((visibility("default")))
int SomeFunc(...)
{
boost::lock_guard<boost::mutex> guard(*gMutex);
....
}
Then, this MyModuleUnInit function registered in .fini_array section (For the reference, other destructor of static C++ variable registered in __cxa_atexit) of the shared library and it is called after mutex use, so program exits normally.
However, I am not confident of the safety of that mutex usage. Are these code is Okay to use? If not, how can I deal with static(global) variable for dlopen-ed shared library?
I'm creating an UI abstraction layer for desktops. Now I'm implementing the functionality of the .NET framework. The annoying thing is that if I let the users create a CLR Windows Forms Application in Visual studio they can't use all the standard libraries like std::thread and if I let them create another type of application, the console shows up.
Is there a way to use clr with std::thread or, even better, is there a way to prevent the console from starting (or hide it from both the screen and the taskbar)with a CLR Console or CLR Empty project.
Thanks
Might be an old question, but I looked into this same problem before. Since CLR does not allow you to include std::thead at compile time, you could try to use it only at linking time. Normally you could resolve this be forward declaring the class in your header and including them only in your cpp files. However you can forward declare your own classes in header files, but you can't for classes in namespace std. According to the C++11 standard, 17.6.4.2.1:
The behavior of a C++ program is undefined if it adds declarations or
definitions to namespace std or to a namespace within namespace std
unless otherwise specified.
A workaround for this problem is to create a threading class that inherits from std::thread that you can forward declare. The header file for this class would look like:
#pragma once
#include <thread>
namespace Threading
{
class Thread : std::thread
{
public:
template<class _Fn, class... _Args> Thread(_Fn fn, _Args... args) : std::thread(fn, std::forward<_Args>(args)...)
{
}
private:
};
}
In the header file that you would like to use the thread you can do forward declare it like:
#pragma once
// Forward declare the thread class
namespace Threading { class Thread; }
class ExampleClass
{
public:
ExampleClass();
void ThreadMethod();
private:
Threading::Thread * _thread;
};
In your source file you can then use the theading class like:
#include "ExampleClass.h"
#include "Thread.h"
ExampleClass::ExampleClass() :
{
_thread = new Threading::Thread(&ExampleClass::ThreadMethod, this);
}
void ExampleClass::ThreadMethod()
{
}
Hope it might help anyone.
This is an old question, but in case someone hits the same problem: boost::thread is an "affordable" and practical replacement (provided you can use boost in your project). Strangely, it bypasses the incompatibility.
As a follow up to an older question of mine, I wish to implement a client-server mockup simulation, where the client initiates a sequence of actions that involve calling methods on the server, which, in turn, can call methods on the client (let's ignore the issue that the stack may blow up).
More specifically, since I want to split the implementation from the definition, I will have server.h and server.cpp for the Server class and client.h and client.cpp for the Client class. Since Server holds a reference to Client and calls methods from it, it needs to #include "client.h". Also, Client holds a reference to Server and calls methods from it, it needs to #include "server.h". At this point, even if I use header guards in both server.h and client.h, it still messes up (yeah, it's expected) so I decided to forward-declare the Server class in client.h and the Client class in server.h. Unfortunately, this is not enough to solve the issue, because I'm also calling methods from the two classes, so I managed to make it compile & run (properly, as far as I can tell), by including server.h in client.cpp and client.h in server.cpp.
Does the above "hack" sound reasonable? Should I expect some unforeseen consequences? Is there any "smarter" way to do this without having to implement a proxy class?
Here's a rudimentary sample of how the implementation will look like:
file client.h:
#ifndef CLIENT_H
#define CLIENT_H
#include <iostream>
#include <memory>
class Server;
class Client
{
private:
std::shared_ptr<const Server> server;
public:
Client () {}
void setServer (const std::shared_ptr<const Server> &server);
void doStuff () const;
void doOtherStuff () const;
};
#endif
file client.cpp:
#include "client.h"
#include "server.h"
void Client::setServer (const std::shared_ptr<const Server> &server)
{
this->server = server;
}
void Client::doStuff () const
{
this->server->doStuff();
}
void Client::doOtherStuff () const
{
std::cout << "All done!" << std::endl;
}
file server.h:
#ifndef SERVER_H
#define SERVER_H
#include <iostream>
#include <memory>
class Client;
class Server
{
private:
std::weak_ptr<const Client> client;
public:
Server () {}
void setClient (const std::weak_ptr<const Client> &client);
void doStuff () const;
};
#endif
file sever.cpp:
#include "server.h"
#include "client.h"
void Server::setClient (const std::weak_ptr<const Client> &client)
{
this->client = client;
}
void Server::doStuff () const
{
this->client.lock()->doOtherStuff();
}
file main.cpp:
#include <iostream>
#include <memory>
#include "client.h"
#include "server.h"
int main ()
{
std::shared_ptr<Client> client(new Client);
std::shared_ptr<Server> server(new Server);
client->setServer(server);
server->setClient(client);
client->doStuff();
return 0;
}
That looks good to me. Forward declaring server in the client.h and forward declaring client in the server.h is the right thing to do.
It is perfectly fine to then include both header files in the .c or .cpp file - all you need to avoid is including the header files in a circle.
The "Hack" is none, it's perfectly common practice to separate declaration and implementation of the two classes as you did. And it's perfectly normal that the *.cpp include both Headers.
Sidenote: First consider different signatures for your setServer and setClient methods: In both methods, you copy the argument. Both copies are nontrivial, since the use_counts and/or weak_count have to be updated. If the argument indeed is an existing argument, that is ok, but if it is a temporary, the copy will increase the count and destruction of the temporary will decrease it again, each time an internal pointer has to be dereferenced. In contrast, moving a shared_ptr or weak_ptr does not affect the use counts but resets the temporary. Destruction of that reset temporary again does not affect the use count (it effectively is a null pointer).
Secondly, always prefer make_shared over simple new, because it saves you one allocation. So use this implementation instead:
void Client::setServer (std::shared_ptr<const Server> server)
{
this->server = std::move(server);
}
int main ()
{
auto client = std::make_shared<Client>(); //prefer make_shared
auto server = std::make_shared<Server>();
/* 1 */
client->setServer(server); //by copy, if you need to continue to use server
/* 2 */
server->setClient(std::move(client)); //by moving
}
Call 1 will be as expensive at it was, you make one copy pf the shared_ptr, only this time you make it while passing the argument, not inside the method. Call 2 will be cheaper, because the shared_ptr is moved around and never copied.
My following statement is false (see comments) and applies only to unique_ptr, not to shared_ptr:
But: Since you use a std::shared_ptr<const Server> in Client, you
will have to define Client's destructor inside client.cpp. The
reason is that if you don't, the compiler will generate it for you,
calling the shared_ptr's and thus Server's destructor which has
not been declared inside client.h. At reasonably high warning levels
you compiler should complain about calling delete on a an undefined
class' pointer.
Does the above "hack" sound reasonable? Should I expect some
unforeseen consequences? Is there any "smarter" way to do this without
having to implement a proxy class?
Forward declaration and use include directive to is the normal and right way to break circular include.
I'm racking my brain trying to find out how to write cross platform classes while avoiding the cost of virtual functions and any kind of ugliness in the platform specific versions of classes. Here is what I have tried.
PlatformIndependantClass.hpp
class PlatformIndependantClass {
public:
PlatformIndependantClass();
std::string GetPlatformName();
private:
PlatformIndependantClass* mImplementation;
};
LinuxClass.hpp
#include "PlatformIndependantClass.hpp"
class LinuxClass : public PlatformIndependantClass{
public:
std::string GetPlatformName();
};
WindowsClass.hpp
#include "PlatformIndependantClass.hpp"
class WindowsClass : public PlatformIndependantClass {
public:
std::string GetPlatformName();
};
PlatformIndependantClass.cpp
#include "PlatformIndependantClass.hpp"
#include "LinuxClass.hpp"
#include "WindowsClass.hpp"
PlatformIndependantClass::PlatformIndependantClass() {
#ifdef TARGET_LINUX
mImplementation = new LinuxClass();
#endif
#ifdef TARGET_WINDOWS
mImplementation = new WindowsClass();
#endif
}
std::string PlatformIndependantClass::GetPlatformName() {
return mImplementation->GetPlatformName();
}
LinuxClass.cpp
#include "LinuxClass.hpp"
std::string LinuxClass::GetPlatformName() {
return std::string("This was compiled on linux!");
}
WindowsClass.cpp
#include "WindowsClass.hpp"
std::string WindowsClass::GetPlatformName() {
return std::string("This was compiled on windows!");
}
main.cpp
#include <iostream>
#include "PlatformIndependantClass.hpp"
using namespace std;
int main()
{
PlatformIndependantClass* cl = new PlatformIndependantClass();
cout << "Hello world!" << endl;
cout << "Operating system name is: " << cl->GetPlatformName() << endl;
cout << "Bye!" << endl;
return 0;
}
Now, this compiles fine but I get a segmentation fault. I believe this is because the platform specific classes inherit from PlatformIndependantClass, which on construction, creates an instance of the platform specific class, so I get infinite recursion. Every time I try, I just get extremely confused!
How can I achieve a design like this properly? Or is this just a horrible idea. I have been trying to find out how to write cross platform classes but I just get a load of results about cross platform libraries, any help will be gratefully accepted :)
I think what you are trying to accomplish can be accomplished much easier...
Object.h:
#include <normal includes>
#if WINDOWS
#include <windows includes>
#endif
#if LINUX
#include <linux includes>
#endif
class Object
{
private:
#if WINDOWS
//Windows Specific Fields...
#endif
#if LINUX
//Linux Specific Fields...
#endif
public:
//Function that performs platform specific functionality
void DoPlatformSpecificStuff();
//Nothing platform specific here
void DoStuff();
};
Object.cpp
#include "Object.h"
void Object::DoStuff() { ... }
ObjectWin32.cpp
#if WINDOWS
#include "Object.h"
void Object::DoPlatformSpecificStuff()
{
//Windows specific stuff...
}
#endif
ObjectLinux.cpp
#if LINUX
#include "Object.h"
void Object::DoPlatformSpecificStuff()
{
//Linux specific stuff...
}
#endif
And so on. I think this could accomplish what you are trying in a bit easier fashion. Also, no virtual functions needed.
Starting from the end, yes, truly a horrible idea, as are most ideas that start with "I want to avoid the cost of virtual functions".
As to why you're getting the segmentation fault (stack overflow specifically), it's because you aren't using virtual functions, but static linking. The compiler doesn't know that mImplementation is anything but a PlatformIndependantClass, so when you try to call return mImplementation->GetPlatformName() you're calling the same function over and over.
What you achieved is called shadowing, you're using compile-time function resolution. The compiler will call the GetPlatformName function of the actual type of the variable you're calling it from, since there's no virtual table to overwrite the pointers to the actual functions. Since mImplementation is PlatformIndependantClass, mImplementation->GetPlatformName will always be PlatformIndependantClass::GetPlatformName.
Edit: Of course the question of why you need to create both a Windows and a Linux copy of your engine at the same time comes to mind. You'll never use both of them at the same time, right?
So why not just have two different libraries, one for each system, and link the right one from your makefile. You get the best of all worlds!
Instead of using the constructor to build the platform-specific instance, I would create a static factory method to create the instances:
PlatformIndependantClass* PlatformIndependantClass::getPlatformIndependantClass() {
#ifdef TARGET_LINUX
return new LinuxClass();
#endif
#ifdef TARGET_WINDOWS
return new WindowsClass();
#endif
}
This way you avoid the recursion, and you also don't need your mImplementation pointer.
I would also try to avoid platform-specific classes, but that's another story :)
When you want to have polymorphic behavior without any run-time overhead, you can try the curiously recurring template pattern (CRTP). The base class is a template, and the derived class uses itself as the template parameter for the base. This requires your classes to be defined as templates, which further restricts them to be implemented completely in the header (.hpp) files.
I'm not sure how to apply the pattern in your particular case.
I don't think the constructor is causing the infinite recursion. It's the GetPlatformName() function. Because it's not set as virtual, it can only call itself.
Two solutions: Make that function virtual, or do away with the inheritance completely.
Either way, the cost of a function only calling another function will be more expensive than using virtual functions in the first place. So I would say keep the inheritance, and virtualize the functions specific to the platform, and call them directly, without going through a base class function.
You are correct about the infinte loop. The fix is actually easier than you'd think.
PlatformIndependantClass.hpp
#include //portable headers
struct PlatformDependantClass; //defined in Cpp file
class PlatformIndependantClass {
public:
PlatformIndependantClass();
~PlatformIndependantClass();
std::string GetPlatformName();
private:
std::unique_ptr<PlatformDependantClass> mImplementation; //note, different type
};
LinuxClass.cpp
#ifdef __GNUC__
#include //linux headers
#include "PlatformIndependantClass.hpp"
struct PlatformDependantClass { //linux only stuff
//stuff
};
PlatformIndependantClass() {
mImplementation.reset(new PlatformDependantClass );
}
~PlatformIndependantClass() {
}
std::string PlatformIndependantClass::GetPlatformName() {
return std::string("This was compiled on linux!");
}
#endif //__GNUC__
WindowsClass.cpp
#ifdef _MSC_VER
#include //windows headers
#include "PlatformIndependantClass.hpp"
struct PlatformDependantClass { //windows only stuff
//stuff
};
PlatformIndependantClass() {
mImplementation.reset(new PlatformDependantClass );
}
~PlatformIndependantClass() {
}
std::string PlatformIndependantClass::GetPlatformName() {
return std::string("This was compiled on Windows!");
}
#endif //_MSC_VER
There's only ONE class defined here. In windows, it only compiles and contains windows stuff, and in Linux, it only compiles and contains linux stuff. Note that the void* thing is called an "Opaque pointer" or "pimpl idiom" http://en.wikipedia.org/wiki/Opaque_pointer