Boost::thread, glut and data sharing - multithreading

I think I have a problem in my program.
I must create an object that continuosly communicate with an external tracking system and get coordinates of point from it.
I wrapped this class inside a boost::thread and before the first calls to my Glut Application I create the thread object and I detach it
The code for the salient methods of the class is the following
boost::mutex resourceMutex;
void Tracker::init()
{
boost::mutex::scoped_lock lock(resourceMutex);
try
{
// some initializations
}
catch (std::bad_alloc const&)
{
cerr << "Memory allocation fail during init!" << endl;
}
try
{
p3dData = (Position3d*)calloc( NUM_MARKERS , sizeof( Position3d ) );
if ( p3dData==NULL )
throw std::bad_alloc();
}
catch ( std::bad_alloc const&)
{
cerr << "Memory allocation fail during memory allocation!" << endl;
}
}
void Tracker::update()
{
boost::mutex::scoped_lock lock(optotrakResourceMutex);
//... operations on vector< Eigen::Vector3d > points
}
vector<Eigen::Vector3d> &Tracker::getAllPoints()
{
return points;
}
My glutTimerFunc makes a call to an update function that every frame picks the points with the method getAllPoints, while the tracker thread continuosly update them (in fact the frequencies of access to data are different, the thread calls to is faster than the glut update functions calls.
Now when the program exit, I first delete the Tracker object allocated with new then interrupt the thread containing it, but sometimes I get strange behaviours I think they are memory leak
Is the way of getting data with different frequencies of access and the use of scoped_lock correct or should I put some guard in the getAllPoints method?

I understand your dedicated tracker thread continuously calls Tracker::update() to acquire the localization data from your device (NDI Optotrak?)
Then, your OpenGL application accesses the latest points at regular interval from the main thread using Tracker::getAllPoints().
In this case, the vector of 3D points Tracker::points is a shared resource between these two threads.
To prevent concurrent access, both the writing operation in update() and the reading with getAllPoints() must be protected by the mutex, not only the writing as in your current code. The reading code in the main thread must also lock the mutex:
// In your main application:
void timerFunc()
{
Tracker* tracker = ...; // Obtain a pointer to the tracker object
tracker->LockResourceMutex(); // Enter critical section
vector< Eigen::Vector3d >& pointsRef = tracker->getAllPoints();
//... operations on points, protected by the mutex
tracker->UnlockResourceMutex(); // Leave critical section
}
// In class Tracker:
void Tracker::LockResourceMutex() { optotrakResourceMutex.lock(); }
void Tracker::UnlockResourceMutex() { optotrakResourceMutex.unlock(); }
Caveat: If your operations on points in the timerFunc() are slow, then the mutex will remain locked for a long time and your tracker thread will block on it when calling Tracker::update().
A better design would be to change Tracker::getAllPoints() to return a copy of the 3D points vector instead of a reference:
// In class Tracker:
vector<Eigen::Vector3d> Tracker::getAllPoints()
{
boost::mutex::scoped_lock lock(optotrakResourceMutex);
return points; // Will call the std::vector() copy constructor
}
// In your main application:
void timerFunc()
{
Tracker* tracker = ...; // Obtain a pointer to the tracker object
vector< Eigen::Vector3d > myPoints = tracker->getAllPoints();
//... operations on your own copy if points
}
Note how the mutex is encapsulated in the Tracker class and how the timerFunc() does not need to worry about it.
Also note how the mutex is locked only during the copy. The copy of a list of 3D vectors is certainly going to be faster than mathematical operations on them.

Related

How to move/swap a std::vector efficiently and thread safe?

Imagine a thread which continuously writes to a vector of strings which is being collected every now and then by another thread (see code).
#include <string>
#include <vector>
#include <chrono>
#include <thread>
#include <iostream>
#include <cassert>
// some public vector being filled by one and consumed by another
// thread
static std::vector<std::string> buffer;
// continuously writes data to buffer (has to be fast)
static const auto filler(std::thread([] {
for (size_t i = 0;; ++i) {
buffer.push_back(std::to_string(i));
}
}));
// returns collected data and clears the buffer being written to
std::vector<std::string> fetch() {
return std::move(buffer);
}
// continuously fetch buffered data and process it (can be slow)
int main() {
size_t expected{};
for(;;) {
std::this_thread::sleep_for(std::chrono::seconds(1));
const auto fetched(fetch());
for (auto && e : fetched) {
size_t read(std::stoi(e));
std::cout << read << " " << expected << std::endl;
assert(read == expected);
++expected;
}
}
}
The provided example generally does what I want it to do but it crashes because it's not thread safe. Obvious approaches would be
to secure the shared vector using a lock_guard
using two buffers and an atomic pointer
using a thread safe vector implementation.
The provided scenario seems very simple to me. I don't think I need a thread safe vector because that would cover a lot more scenarios at the cost of performance.
Using a mutex or swapping between two instances of the vector seem plausible to me but I wonder if there is some solution specially made to 'atomically grab all data and leave an empty container'.
Maybe there's an obvious solution and it's just time to go to bed for me?
Important note: this question is somewhat academical since performance is not (necessarily) a real issue here. The provided example gets throttled by about 15% but there is hardly any 'real' work being done. I think in a real world example the benefit would be about 2-5%
First of all I would not recommend to have a non-const static variable. So I propose to encapsulate vector with a class with the following interface
class ValuesHolder
{
public:
void push_back(std::string value);
std::vector<std::string> take();
};
The second note about 'atomically grab all data and leave an empty container' - you could make this trick with swapping pointers but the main issue is that push_back should be in a sync with it (during the push_back is executed vector shouldn't be moved). Otherwise there may be issues with the following workflow
Thead 1 Thread 2
auto values = holder.take(); // push_back starts before take
for (const auto& value : values) // but value is inserted during the iteration
{...}
So the first option is just to lock during both calls:
class ValuesHolder
{
public:
void push_back(std::string value)
{
std::lock_guard<std::mutex> lock(mut);
values.push_back(std::move(value));
}
std::vector<std::string> take()
{
std::lock_guard<std::mutex> lock(mut);
return std::move(values);
}
private:
std::mutex mut;
std::vector<std::string> values;
};
Otherwise you could switch from std::vector to lock-free stack container. However the performance should be accurately measured since the number of allocations can increase, so the performance can be worser.

C++/Cli synchronizing threads writing to file

I am trying to synchronize threads writing data to a text file in a class by using Monitor, but in my code it seems that the else statement is never evaluated, is this the correct use of monitor for thread synchronization?
void Bank::updatefile()
{
Thread^ current = Thread::CurrentThread;
bool open = false;
current->Sleep(1000);
while (!open)
{
if (Monitor::TryEnter(current))
{
String^ fileName = "accountdata.txt";
StreamWriter^ sw = gcnew StreamWriter(fileName);
for (int x = 0; x < 19; x++)
sw->WriteLine(accountData[x]);
sw->Close();
Monitor::Pulse;
Monitor::Exit(current);
current->Sleep(500);
open = true;
}
else
{
Monitor::Wait(current);
current->Sleep(500);
}
}
}
You're passing an object to Monitor::TryEnter that is specific to the thread in which it is executing (i.e. Thread^ current = Thread::CurrentThread;). No other threads are using the same object (they're using the one for their own thread). So there's never a collision or locking conflict.
Try creating some generic object that's shared among the threads, something higher up in the Bank class. Then use that for your TryEnter call.
Your use of Monitor is partially correct. The object you're using for locking is not correct.
Monitor
Monitor::Pulse is unnecessary here. Just Exit the monitor, and the next thread will be able to grab the lock.
Monitor::Wait is incorrect here: Wait is supposed to be used when the thread has the object already locked. Here, you have the object not locked yet.
In general, Pulse and Wait are rarely used. For locking for exclusive access to a shared resource, Enter, TryEnter, and Exit are all you need.
Here's how your use of Monitor should be written:
Object^ lockObj = ...;
bool done = false;
while(!done)
{
if(Monitor::TryEnter(lockObj, 500)) // wait 500 millis for the lock.
{
try
{
// do work
done = true;
}
finally
{
Monitor::Exit(lockObj);
}
}
else
{
// Check some other exit condition?
}
}
or if the else is empty, you can simplify it like this:
Object^ lockObj = ...;
Monitor::Enter(lockObj); // Wait forever for the lock.
try
{
// do work
}
finally
{
Monitor::Exit(lockObj);
}
There is a class that Microsoft provides that makes this all easier: msclr::lock. This class, used without the ^, makes use of the destructor to release the lock, without a try-finally block.
#include <msclr\lock.h>
bool done = false;
while(!done)
{
msclr::lock lock(lockObj, lock_later);
if (lock.try_acquire(500)) // wait 500 millis for the lock to be available.
{
// Do work
done = true;
}
} // <-- Monitor::Exit is called by lock class when it goes out of scope.
{
msclr::lock lock(lockObj); // wait forever for the lock to be available.
// Do work
} // <-- Monitor::Exit is called by lock class when it goes out of scope.
The object to lock on
Thread::CurrentThread is going to return a different object on each thread. Therefore, each thread attempts to lock on a different object, and that's why all of them succeed. Instead, have one object, created before you spawn your threads, that is used for locking.
Also, instead of opening & closing the file on each thread, it would be more efficient to open it once, before the threads are spawned, and then just use that one StreamWriter from each of the threads. This also gives you a obvious object to lock on: You can pass the StreamWriter itself to Monitor::Enter or msclr::lock.

How to send signal/data from a worker thread to main thread?

I'll preface this by saying that I'm delving into multithreading for the first time. Despite a lot of reading on concurrency and synchronization, I'm not readily seeing a solution for the requirements I've been given.
Using C++11 and Boost, I'm trying to figure out how to send data from a worker thread to a main thread. The worker thread is spawned at the start of the application and continuously monitors a lock free queue. Objects populate this queue at various intervals. This part is working.
Once the data is available, it needs to be processed by the main thread since another signal will be sent to the rest of the application which cannot be on a worker thread. This is what I'm having trouble with.
If I have to block the main thread through a mutex or a condition variable until the worker thread is done, how will that improve responsiveness? I might as well just stay with a single thread so I have access to the data. I must be missing something here.
I have posted a couple questions, thinking that Boost::Asio was the way to go. There is an example of how signals and data can be sent between threads, but as the responses indicate, things get quickly overly-complicated and it's not working perfectly:
How to connect signal to boost::asio::io_service when posting work on different thread?
Boost::Asio with Main/Workers threads - Can I start event loop before posting work?
After speaking with some colleagues, it was suggested that two queues be used -- one input, one output. This would be in shared space and the output queue would be populated by the worker thread. The worker thread is always going but there would need to be a Timer, probably at the application level, that would force the main thread to examine the output queue to see if there were any pending tasks.
Any ideas on where I should direct my attention? Are there any techniques or strategies that might work for what I'm trying to do? I'll be looking at Timers next.
Thanks.
Edit: This is production code for a plugin system that post-processes simulation results. We are using C++11 first wherever possible, followed by Boost. We are using Boost's lockfree::queue. The application is doing what we want on a single thread but now we are trying to optimize where we see that there are performance issues (in this case, a calculation happening through another library). The main thread has a lot of responsibilities, including database access, which is why I want to limit what the worker thread actually does.
Update: I have already been successful in using std::thread to launch a worker thread that examines a Boost lock::free queue and processes tasks placed it in. It's step 5 in #Pressacco's response that I'm having trouble with. Any examples returning a value to the main thread when a worker thread is finished and informing the main thread, rather than simply waiting for the worker to finish?
If your objective is develop the solution from scratch (using native threads, queues, etc.):
create a thread save queue queue (Mutex/CriticalSection around add/remove)
create a counting semaphore that is associated with the queue
have one or more worker threads wait on the counting semaphore (i.e. the thread will block)
the semaphore is more efficient than having the thread constantly poll the queue
as messages/jobs are added to the queue, increment the semaphore
a thread will wake up
the thread should remove one message
if a result needs to be returned...
setup another: Queue+Semaphore+WorkerThreads
ADDITIONAL NOTES
If you decide to implement a thread safe queue from scratch, take a look at:
Synchronization between threads using Critical Section
With that said, I would take another look at BOOST. I haven't used the library, but from what I hear it will most likely contain some relevant data structures (e.g. a thread safe queue).
My favorite quote from the MSDN:
"When you use multithreading of any sort, you potentially expose
yourself to very serious and complex bugs"
SIDEBAR
Since you are looking at concurrent programming for the first time, you may wish to consider:
Is your objective to build production worthy code , or is this simply a learning exercise?
production? consider us existing proven libraries
learning? consider writing the code from scratch
Consider using a thread pool with an asynchronous callback instead of native threads.
more threads != better
Are threads really needed?
Follow the KISS principle.
The feedback above led me in the right direction for what I needed. The solution was definitely simpler than having to use signals/slots or Boost::Asio as I had previously attempted. I have two lock-free queues, one for input (on a worker thread) and one for output (on the main thread, populated by the worker thread). I use a timer to schedule when the output queue is processed. The code is below; perhaps it is of use to somebody:
//Task.h
#include <iostream>
#include <thread>
class Task
{
public:
Task(bool shutdown = false) : _shutdown(shutdown) {};
virtual ~Task() {};
bool IsShutdownRequest() { return _shutdown; }
virtual int Execute() = 0;
private:
bool _shutdown;
};
class ShutdownTask : public Task
{
public:
ShutdownTask() : Task(true) {}
virtual int Execute() { return -1; }
};
class TimeSeriesTask : public Task
{
public:
TimeSeriesTask(int value) : _value(value) {};
virtual int Execute()
{
std::cout << "Calculating on thread " << std::this_thread::get_id() << std::endl;
return _value * 2;
}
private:
int _value;
};
// Main.cpp : Defines the entry point for the console application.
#include "stdafx.h"
#include "afxwin.h"
#include <boost/lockfree/spsc_queue.hpp>
#include "Task.h"
static UINT_PTR ProcessDataCheckTimerID = 0;
static const int ProcessDataCheckPeriodInMilliseconds = 100;
class Manager
{
public:
Manager()
{
//Worker Thread with application lifetime that processes a lock free queue
_workerThread = std::thread(&Manager::ProcessInputData, this);
};
virtual ~Manager()
{
_workerThread.join();
};
void QueueData(int x)
{
if (x > 0)
{
_inputQueue.push(std::make_shared<TimeSeriesTask>(x));
}
else
{
_inputQueue.push(std::make_shared<ShutdownTask>());
}
}
void ProcessOutputData()
{
//process output data on the Main Thread
_outputQueue.consume_one([&](int value)
{
if (value < 0)
{
PostQuitMessage(WM_QUIT);
}
else
{
int result = value - 1;
std::cout << "Final result is " << result << " on thread " << std::this_thread::get_id() << std::endl;
}
});
}
private:
void ProcessInputData()
{
bool shutdown = false;
//Worker Thread processes input data indefinitely
do
{
_inputQueue.consume_one([&](std::shared_ptr<Task> task)
{
std::cout << "Getting element from input queue on thread " << std::this_thread::get_id() << std::endl;
if (task->IsShutdownRequest()) { shutdown = true; }
int result = task->Execute();
_outputQueue.push(result);
});
} while (shutdown == false);
}
std::thread _workerThread;
boost::lockfree::spsc_queue<std::shared_ptr<Task>, boost::lockfree::capacity<1024>> _inputQueue;
boost::lockfree::spsc_queue<int, boost::lockfree::capacity<1024>> _outputQueue;
};
std::shared_ptr<Manager> g_pMgr;
//timer to force Main Thread to process Manager's output queue
void CALLBACK TimerCallback(HWND hWnd, UINT nMsg, UINT nIDEvent, DWORD dwTime)
{
if (nIDEvent == ProcessDataCheckTimerID)
{
KillTimer(NULL, ProcessDataCheckPeriodInMilliseconds);
ProcessDataCheckTimerID = 0;
//call function to process data
g_pMgr->ProcessOutputData();
//reset timer
ProcessDataCheckTimerID = SetTimer(NULL, ProcessDataCheckTimerID, ProcessDataCheckPeriodInMilliseconds, (TIMERPROC)&TimerCallback);
}
}
int main()
{
std::cout << "Main thread is " << std::this_thread::get_id() << std::endl;
g_pMgr = std::make_shared<Manager>();
ProcessDataCheckTimerID = SetTimer(NULL, ProcessDataCheckTimerID, ProcessDataCheckPeriodInMilliseconds, (TIMERPROC)&TimerCallback);
//queue up some dummy data
for (int i = 1; i <= 10; i++)
{
g_pMgr->QueueData(i);
}
//queue a shutdown request
g_pMgr->QueueData(-1);
//fake the application's message loop
MSG msg;
bool shutdown = false;
while (shutdown == false)
{
if (GetMessage(&msg, NULL, 0, 0))
{
TranslateMessage(&msg);
DispatchMessage(&msg);
}
else
{
shutdown = true;
}
}
return 0;
}

C++11 - Managing worker threads

I am new to threading in C++11 and I am wondering how to manage worker threads (using the standard library) to perform some task and then die off. I have a pool of threads vector<thread *> thread_pool that maintains a list of active threads.
Let's say I launch a new thread and add it to the pool using thread_pool.push_back(new thread(worker_task)), where worker_task is defined as follows:
void worker_task()
{
this_thread::sleep_for(chrono::milliseconds(1000));
cout << "Hello, world!\n"
}
Once the worker thread has terminated, what is the best way to reliably remove the thread from the pool? The main thread needs to run continuously and cannot block on a join call. I am more confused about the general structure of the code than the intricacies of synchronization.
Edit: It looks like I misused the concept of a pool in my code. All I meant was that I have a list of threads that are currently running.
You can use std::thread::detach to "separate the thread of execution from the thread object, allowing execution to continue independently. Any allocated resources will be freed once the thread exits."
If each thread should make its state visible, you can move this functionality into the thread function.
std::mutex mutex;
using strings = std::list<std::string>;
strings info;
strings::iterator insert(std::string value) {
std::unique_lock<std::mutex> lock{mutex};
return info.insert(info.end(), std::move(value));
}
auto erase(strings::iterator p) {
std::unique_lock<std::mutex> lock{mutex};
info.erase(p);
}
template <typename F>
void async(F f) {
std::thread{[f] {
auto p = insert("...");
try {
f();
} catch (...) {
erase(p);
throw;
}
erase(p);
}}.detach();
}

C++11 When To Use A Memory Fence?

I'm writing some threaded C++11 code, and I'm not totally sure on when I need to use a memory fence or something. So here is basically what I'm doing:
class Worker
{
std::string arg1;
int arg2;
int arg3;
std::thread thread;
public:
Worker( std::string arg1, int arg2, int arg3 )
{
this->arg1 = arg1;
this->arg2 = arg2;
this->arg3 = arg3;
}
void DoWork()
{
this->thread = std::thread( &Worker::Work, this );
}
private:
Work()
{
// Do stuff with args
}
}
int main()
{
Worker worker( "some data", 1, 2 );
worker.DoWork();
// Wait for it to finish
return 0;
}
I was wondering, what steps do I need to take to make sure that the args are safe to access in the Work() function which runs on another thread. Is it enough that it's written in the constructor, and then the thread is created in a separate function? Or do I need a memory fence, and how do I make a memory fence to make sure all 3 args are written by the main thread, and then read by the Worker thread?
Thanks for any help!
The C++11 standard section 30.3.1.2 thread constructors [thread.thread.constr] p5 describes the constructor template <class F, class... Args> explicit thread(F&& f, Args&&... args):
Synchronization: the completion of the invocation of the constructor synchronizes with the beginning of the invocation of the copy of f.
So everything in the current thread happens before the thread function is called. You don't need to do anything special to ensure that the assignments to the Worker members are complete and will be visible to the new thread.
In general, you should never have to use a memory fence when writing multithreaded C++11: synchronization is built into mutexes/atomics and they handle any necessary fences for you. (Caveat: you are on your own if you use relaxed atomics.)

Resources