Singleton and thread safety - concurrency

When talking about Singletons and threadsafe-ty issues concerning race conditions in creating the singleton instance, which thread are we talking about?
Using this as example, assume I have a MyApp that uses a Singleton
class MyApp
{
MySingleton oneAndOnly;
int main() // application entry point
{
oneAndOnly = MySingleton::GetInstance();
}
void SpawnThreads()
{
for(int i = 0; i < 100; i++)
{
Thread spawn = new Thread(new ThreadStart(JustDoIt));
spawn.Start();
}
}
void JustDoIt()
{
WaitRandomAmountOfTime(); // Wait to induce race condition (maybe?) for next line.
MySingleton localInstance = MySingleton::GetInstance();
localInstance.DoSomething();
}
}
Is it talking about:
when I open the MyApp.exe once, and
then once more again, trying to have
both opened?
Or is it talking about the threads spawned by MyApp? What if MyApp does
not spawn threads?

In Windows threads exist solely within the scope of a process, i.e. the running instance of an application. So thread safety means making sure that shared resources are accessed sequentially from multiple threads within a given process.
In more general terms, race conditions occur as a result of concurrency regardless of scope. For example a distributed application that exposes a shared resource to external processes, is still subject to race conditions if access to that resource isn't properly regulated.

Related

Multithreaded server - design approach

I have a systemd service which acts as a server for incoming requests (API endpoint). Additionally, this service should monitor the state of the system (cpu load, ram, etc.), this is done by reading in the appropriate files in the /proc filesystem. I plan to update these values each second by spawning a dedicated thread, which will continuously read in the new values.
To my understanding a thread pool would be the wrong pattern to apply here, since these threads (probably around 4 in total) are long running (start and termination depends on the lifetime of the service). What would be a proper approach to manage these threads?
In my current implementation I have a dedicated class for each thread with some helper functions:
class Example{
public:
Example() {
t = std::thread{&Example::run, this};
}
~Example() {
t.join();
}
void read(); // read from /proc fs
void set(); // update values
void get(); // access to private data member
void run(); // thread loop, will call read and set each second
std::thread t;
private:
int data; // type int to keep it simple
}
The server then manually starts each thread on startup:
// constructor snippet
// these are member variables
t1 = Example1();
t2 = Example2();
t3 = Example3();
t4 = Example4();
I'm not sure if this is a proper approach to handle multiple, long running threads. Would it be better to create a dedicated class which handles all threads, so that the server would just have to manage this one object? Are there any other patterns for this kind of work?
Also the thread should be the only one updating the corresponding value, but there could be multiple reads happen at the same time, should a mutex be used during the update process?

Can std::threads be created / destroyed from global variables in a Windows DLL?

I'm creating a logging object which performs the real file writing work on a separate std::thread, and offers an interface to a log command buffer, syncing the caller threads and the one worker thread. Access to the buffer is protected by a mutex, there's an atomic bool for the worker thread exit condition, and I'm using Windows native Events as a signal to wake up the worker thread when new commands arrive. The object's constructor spawns the worker thread so it is immediately available. The worker thread is simply a while loop checking the exit condition, with in the loop a blocking wait for the signal. The object's destructor finally just sets the exit condition, signals the thread to wake up and joins it to ensure it's down before the object is fully destroyed.
Seems simple enough, and when using such an object somewhere in a function it works nicely. However, when declaring such an object as a global variable to have it usable for everyone it stops working. I'm on Windows, using Visual Studio 2017 with the 2015 tool chain. My project is a DLL plugin for another application.
The things I tried so far:
Start the thread in the constructor of the global object. This however makes the main thread hang immediately when my DLL is loaded. Pausing the app in the debugger reveals we're in the std lib, at a point where the main thread should have launched the worker thread and is now stuck waiting for a condition variable, presumably one that is signaled by the worker thread once it is launched?
Delay-construct the thread on demand when we first use the global object from somewhere else. This way constructing it goes nicely without a hang. However, when signalling the worker thread to exit from the destructor, the signal is sent, but the join on the worker thread now hangs. Pausing the app in the debugger reveals our main thread is the only one still alive, and the worker thread is already gone? A breakpoint placed in the worker thread function right before the close brace reveals it is never hit; the thread must be getting killed?
I also tried to start the thread via a std::future, starting it up async, and that one launches perfectly fine from the constructor in global objects. However, when the future tries to join the thread in the destructor, it hangs as well; here again no worker thread to be detected anymore while no breakpoint gets hit in it.
What could be going on? I can't imagine it's because the thread construction and destruction takes place outside main() so to speak; these std primitives should really be available at such moments, right? Or is this Windows specific and is the code running in the context of DllMain's DLL_PROCESS_ATTACH / DLL_THREAD_ATTACH events, where starting up threads might wreak havoc due to thread local storage not yet being up and running or such? (would it?)
EDIT -- added code sample
The following is an abbreviation/simplification of my code; it probably doesn't even compile but it gets the point across I hope :)
class LogWriter {
public:
LogWriter() :
m_mayLive(true) {
m_writerThread = std::thread(&C_LogWriter::HandleLogWrites, this); // or in initializer list above, same result
};
~LogWriter() {
m_mayLive = false;
m_doSomething.signal();
if (m_writerThread.joinable()) {
m_writerThread.join();
}
};
void AddToLog(const std::string& line) { // multithreaded client facing interface
{
Locker locker; // Locker = own RAII locker class
Lock(locker); // using a mutex here behind the scenes
m_outstandingLines.push_back(line);
}
m_doSomething.signal();
}
private:
std::list<std::string> m_outstandingLines; // buffer between worker thread and the rest of the world
std::atomic<bool> m_mayLive; // worker thread exit signal
juce::WaitableEvent m_doSomething; // signal to wake up worker thread; no std -- we're using other libs as well
std::thread m_writerThread;
int HandleLogWrites() {
do {
m_doSomething.wait(); // wait for input; no busy loop please
C_Locker locker; // access our line buffer; auto-released at end of loop iteration
Lock(locker);
while (!m_outstandingLines.empty()) {
WriteLineToLog(m_outstandingLines.front());
m_outstandingLines.pop_front();
if (!m_outstandingLines.empty()) {
locker.Unlock(); // don't hog; give caller threads some room to add lines to the buffer in between
std::this_thread::sleep_for(std::chrono::milliseconds(10));
Lock(locker);
}
};
} while (m_mayLive); // atmoic bool; no need to mutex it
WriteLineToLog("LogWriter shut down"); // doesn't show in the logs; breakpoints here also aren't being hit
return 0;
}
void WriteLineToLog(const std::string& line) {
... fopen, fprintf the line, flush, close ...
}
void Lock(C_Locker& locker) {
static LocalLock lock; // LocalLock is similar to std::mutex, though we're using other libs here
locker.Lock(&lock);
}
};
class Logger {
public:
Logger();
~Logger();
void operator() (const char* text, ...) { // behave like printf
std::string newLine;
... vsnprintf -> std::string ...
m_writer.AddToLog(newLine);
}
private:
LogWriter m_writer;
};
extern Logger g_logger; // so everyone can use g_logger("x = %d\n", x);
// no need to make it a Meyer Singleton; we have no other global objects interfering
Since you're writing a DLL in C++, you have to understand how "globals" in DLL's work. The compiler sticks their initialization in DllMain, before anything else that you would do there. But there are some strict rules what you can do in DllMain, as it runs under loader lock. The short summary is that you can't call anything in another DLL because that DLL cannot be loaded while your DllMain is running. Calling CreateThread is definitely not allowed, not even if wrapped inside a std::thread::thread constructor.
The problem with the destructor is quite possibly because your DLL has exited (can't tell without code). The DLL unloads before the EXE, and their respective globals are also cleaned up in that order. Any attempt to log from a destructor in an EXE will fail for obvious reasons.
There is no simple solution here. Andrei Alexandrescu's "Modern C++ Design" has a reasonable solution for logging in the non-DLL case, but you'll need to harden that for use in a DLL. An alternative is to check in your logging functions if your logger still exists. You can use a named mutex for that. If your log function fails in OpenMutex, then either the logger does not exist yet or it no longer exists.
Think I've encountered that destruction issue with DLLs to use with Unity.
The only solution I found back then was to essentially give up true global variables that would need cleanup.
Instead I put them in a separate class which is instantiated only a single time into a global pointer by some custom launch function. Then my DLL got a "quit()" function also called by the user of the DLL. The quit function correctly destroys the instance carrying the global variables.
Probably not the smoothest solution and you have a pointer-indirection on every access to the global variables, but it turned out to be comfortable for serializing the state of the global variables as well.

Multithreaded C++ Program Not Running In Parallel Using vector<thread> and .join()

Note: This is the first post I have made on this site, but I have searched extensively and was not able to find a solution to my problem.
I have written a program which essentially tests all permutations of a vector of numbers to find an optimal sequence as defined by me. Of course, computing permutations of numbers is very time consuming even for small inputs, so I am trying to speed things up by using multithreading.
Here is a small sample which replicates the problem:
class TaskObject {
public:
void operator()() {
recursiveFunc();
}
private:
Solution *bestSolution; //Shared by every TaskObject, but can only be accessed by one at a time
void recursiveFunc() {
if (base_case) {
//Only part where shared object is accessed
//base_case is rarely reached
return;
}
recursiveFunc();
}
};
void runSolutionWithThreads() {
vector<thread> threads(std::thread::hardware_concurrency());
vector<TaskObject> tasks_vector(std::thread::hardware_concurrency());
updateTasks(); //Sets parameters that intialize the first call to recursiveFunc
for (int q = 0; q < (int)tasks_vector.size(); ++q) {
threads[q] = std::thread(tasks_vector[q]);
}
for (int i = 0; i < (int)threads.size(); ++i) {
threads[i].join();
}
}
I imagined that this would enable all threads to run in parallel, but I can see using the performance profiler in visual studio and in the advanced settings of windows task manager that only 1 thread is running at a time. On a system with access to 4 threads, the CPU gets bounded at 25%. I get correct output every time I run, so there are no issues with the algorithm logic. Work is spread out as evenly as possible among all task objects. Collisions with shared data rarely occur. Program implementation with thread pool always ran at nearly 100%.
The objects submitted to the threads don't print to cout and all have their own copies of the data required to perform their work except for one shared object they all reference by pointer.
private:
Solution* bestSolution;
This shared data is not susceptible to a data race condition since I used lock_guard from mutex to make it so only one thread can update bestSolution at a time.
In other words, why isn't my CPU running at nearly 100% for my multithreaded program which uses as many threads as there are available in the system?
I can readily update this post with more information if needed.
In debugging your application, use the debugger to "break all" threads. Then examine each thread with the debug thread window to see where each thread is executing. Likely you will find that only one thread is executing code, while the rest are all blocked on the mutex that the one running thread is holding.
If you show a more complete example of the code it can greatly assist.

Do threads share some class fields?

This is an example from C++ GUI Programming with Qt 4
I have a thread class:
class Thread : public QThread {
Q_OBJECT
public:
Thread();
void setMessage(const QString &message);
void stop();
protected:
void run();
private:
QString messageStr;
volatile bool stopped;
}
This is the relevant implementation of the the class:
Thread::Thread() {
stopped = false;
}
void Thread::run() {
while (!stopped)
std::cerr << qPrintable(messageStr);
stopped = false;
std::cerr << std::endl;
}
void Thread::stop() {
stopped = true;
}
This class is used in a ThreadDialog class which basically have two private fields Thread threadA and Thread threadB. setMessage function is called separately for them and messageStr is set to "A" and "B". Two buttons are declared inside which have clicked signals connected two to slot functions that start or stop those two threads like this:
void ThreadDialog::startOrStopThreadA() {
if (threadA.isRunning()) {
threadA.stop();
threadAButton->setText(tr("Start A"));
} else {
threadA.start();
threadAButton->setText(tr("Stop A"));
}
}
The function for threadB is the same. The problem is this, quoting directly from the book: "The stopped variable is declared volatile because it is accessed from different threads and we want to be sure that it is freshly read every time it is needed. If we omitted the volatile keyword, the compiler might optimize access to the variable, possibly leading to incorrect results."
I can't understand why these two threads would access the same field. Aren't they different instances so they have their own field stopped? Furthermore if stopped field is shared why isn't messageStr field shared too?
I can't understand why these two threads would access the same field. Aren't they different instances
so they have their own field stopped? Furthermore if stopped field is shared why isn't messageStr
field shared too?
That's not what they are saying. The field is not shared among different instances, regardless of whether there are threads involved or not. However an instance might be accessed from different threads, in that regard, the fields might be "shared" among different threads.
They are talking about the case when some other thread wishes to call threadA.stop()
If you have this code:
Thread threadA;
threadA.start();
...
threadA.stop();
There are 2 threads involved:
The thread that runs the above code
The newly created threadA that is started with the threadA.start() call
Now volatile bool stopped is accessed by thread 2 in it's run() function, and it's accessed from thread 1 when it calls threadA.stop().
This is a common confusion in multithreading. You are confusing the thread object class Thread : public QThread with the thread of execution (ie executing instructions).
There is one thread of execution which is running the code ThreadDialog::startOrStopThreadA
There is another thread of execution which is running Thread::run() and which is started by threadA.start().
Both of these threads have access to messageStr and stopped
The two instances threadA and threadB do not share stopped. They are different instances if a same class.
About this statement :
The stopped variable is declared volatile because it is accessed from
different threads and we want to be sure that it is freshly read every
time it is needed.
It means that the stopped variable is accessed from two different running threads. Here the two threads are the main application thread and the one in the run() function. It's unsafe to access the same variable from two different threads.

C++ Gtk threading. Am I doing it right?

I have a gtkmm application and I'm trying to put some long running tasks into separate threads so they don't lock the GUI. Here's a tutorial I've based my design on:
http://www.velvetcache.org/2008/09/30/gtkmmglibmm-thread-example
I use Glib::Dispatcher signals to notify the GUI thread when the work is done or something needs to be updated, however I'm not sure how to pass the data between the worker thread and GUI thread. So far I've been passing a pointer to the class which creates the worker to the worker and then modifying public members of the class, but something tells me it's not the most correct to do it. Here's an example:
class Some_GUI_class
{
public:
std::string thread_message;
private:
Worker_class* worker;
void start_worker()
{
if (worker != NULL) return;
worker = new Worker_class(this);
worker->sig_message.connect(sigc::mem_fun(*this, &Some_GUI_class::display_message_from_thread);
worker.start();
}
void display_message_from_thread()
{
some_label->set_text(thread_message);
}
}
class Worker_class
{
public:
Worker_class(Some_GUI_class* gui_class) : gui_class(gui_class)
{}
void start()
{
thread = Glib::Thread::create(sigc::mem_fun(*this, &Worker_class::run), true);
}
Glib::Dispather sig_message;
protected:
Glib::Thread* thread;
Glib::Mutex mutex;
Some_GUI_class* gui_class;
void run()
{
// ...
gui_class->thread_message = "Message from a thread!";
sig_message();
}
}
This essentialy works, but I guess if the GUI thread wanted to modify thread_message at the same time there would be a problem? Is it safe to do it like this then as long as I'm sure the variables are only modified by a single thread or is there a better way?
You have a race condition. Even if your gui thread doesn't modify thread_message, allowing the GUI thread to read it while another thread is modifying it is not going to give you long term happiness. This is because std::string is not itself protected from multiple threads accessing it, and has multiple internal fields. If one thread is in the process of modifying one of its internal fields, while another is reading them, the internal state will not be consistent from the point of view of the second.
You can use a mutex in the GUI class to protect access to the variables which might be accessed by another thread. Lock and unlock the mutex in get/set routines, and use those routines for all other accesses to ensure that only one thread gets to access or modify the variables at one time.
Generally mutex usage is not enough to achieve the desired behaviour. The same worker thread (or another one if you have it) could want to send another message while first one had not been processed by the main thread yet. That is why in addition to mutex you should use message queue (e.g. object of std::deque<std::string> class) instead of just a std::string Some_GUI_class::thread_message variable to avoid this kind of message loss.