I'm not sure if this is a question regarding programming technique or design but I'm open for suggestions.
The problem: I want to create an abstraction layer between data sources (sensors) and consumers. The idea is that the consumers only "know" the interfaces (abstract base class) of different sensor types. Each of this sensor types usually consists of several individual values which all have their own getter methods.
As an example I will use a simplified GPS sensor.
class IGpsSensor {
public:
virtual float getLongitude() = 0;
virtual float getLatitude() = 0;
virtual float getElevation() = 0;
// Deviations
virtual float getLongitudeDev() = 0;
virtual float getLatitudeDev() = 0;
virtual float getElevationDev() = 0;
virtual int getNumOfSatellites() = 0;
};
Since updates to the sensor are done by a different thread (details are up to the implementation of the interface), synchronizing getters and also the update methods seems like a reasonable approach to ensure consistency.
So far so good. In most cases this level of synchronization should suffice. However, sometimes it might be necessary to aquire more than one value (with consecutive getXXX() calls) and ensure that no update is happening in between. Whether this is necessary or not (and which values are important) is up to the consumer.
Sticking to the example, in a lot of cases it is only important to know longitude and latitude (but hopefully both relating to the same update()). I admit that this could be done be grouping them together into a "Position" class or struct. But a consumer might also use the sensor for a more complicated algorithm and requires the deviation as well.
Now I was wondering, what would be a proper way to do this.
Solutions I could think of:
Group all possible values into a struct (or class) and add an additional (synchronized) getter returning copies of all values at once - seems like a lot of unnecessary overhead to me in case only 2 or 3 out of maybe 10 values are needed.
Add a method returning a reference to the mutex used within the data source to allow locking by the consumer - this doesn't feel like "good design". And since getters are already synchronized, using a recursive mutex is mandatory. However, I assume that there are multiple readers but only one writer and thus I'd rather go with a shared mutex here.
Thanks for your help.
How about exposing a "Reader" interface? To get the reader object, you would do something like this:
const IGpsSensorReader& gps_reader = gps_sensor.getReader();
The IGpsSensorReader class could have access to protected members of the IGpsSensor class. When constructed, it would acquire the lock. Upon destruction, it would release the lock. An accessor could do something like this:
{ //block that accesses attributes
const IGpsSensorReader& gps_reader = gps_sensor.getReader();
//read whatever values from gps_reader it needs
} //closing the scope will destruct gps_reader, causing an unlock
You could also expose a getWriter method to the thread doing the updates. Internally, you could use boost's shared_mutex to mediate access between the readers and the writers.
A technique I've used in some simple projects is to only provide access to a proxy object. This proxy object holds a lock for the duration of its lifetime, and provides the actual interface to my data. This access does no synchronization itself, because it is only available through the proxy which is already locked appropriately. I've never tried expanding this to a full scale project, but it has seemed to work well for my purposes.
Possible solution: derive all your source classes from
class Transaction {
pthread_mutex_t mtx;
// constructor/destructor
public:
void beginTransaction() { pthread_mutex_lock(&mtx); } // ERROR CHECKING MISSING
void endTransaction() { pthread_mutex_unlock(&mtx); } // DO ERROR CHECKING
protected:
// helper method
int getSingle(int *ptr)
{ int v; beginTransaction(); v=*ptr; endTransaction(); return v; }
};
If you need to read out multiple values, use begin/endTransaction methods. To define your getValue functions, just call getSingle with pointer to the appropriate member [this is just a convenience method so that you don't have to call begin/endTransaction in each getValue function.].
You will need to flesh out some details, because if your getValue functions use begin/endTransaction, you won't be able to call them inside a transaction. (A mutex can be locked only once, unless it is configured to be recursive.)
Related
I have a "Device" class representing the connection of a peripheral hardware device. Scores of member functions ("device functions") are called on each Device object by clients.
class Device {
public:
std::timed_mutex mutex_;
void DeviceFunction1();
void DeviceFunction2();
void DeviceFunction3();
void DeviceFunction4();
// void DeviceFunctionXXX(); lots and lots of device functions
// other stuff
// ...
};
The Device class has a member std::timed_mutex mutex_ which must be locked by each of the device functions prior to communicating with the device, to prevent communication with the device simultaneously from concurrent threads.
An obvious but repetitive and cumbersome approach is to copy/paste the mutex_.try_lock() code at the top of the execution of each device function.
void Device::DeviceFunction1() {
mutex_.try_lock(); // this is repeated in ALL functions
// communicate with device
// other stuff
// ...
}
However, I'm wondering if there is a C++ construct or design pattern or paradigm which can be used to "group" these functions in such a way that the mutex_.try_lock() call is "implicit" for all functions in the group.
In other words: in a similar fashion that a derived class can implicitly call common code in a base class constructor, I'd like to do something similar with functions calls (instead of class inheritance).
Any recommendations?
First of all, if the mutex must be locked before you do anything else, then you should call mutex_.lock(), or at least not ignore the fact that try_lock may actually fail to lock the mutex. Also, manually placing calls to lock and unlock a mutex is extremely error-prone and can be much harder to get right than you might think. Don't do it. Use, e.g., an std::lock_guard instead.
The fact that you're using an std::timed_mutex suggests that what's actually going on in your real code may be a bit more involved (what for would you be using an std::timed_mutex otherwise). Assuming that what you're really doing is something more complex than just calling try_lock and ignoring its return value, consider encapsulating your complex locking procedure, whatever it may be, in a custom lock guard type, e.g.:
class the_locking_dance
{
auto do_the_locking_dance(std::timed_mutex& mutex)
{
while (!mutex.try_lock_for(100ms))
/* do whatever it is that you wanna do */;
return std::lock_guard { mutex, std::adopt_lock_t };
}
std::lock_guard<std::timed_mutex> guard;
public:
the_locking_dance(std::timed_mutex& mutex)
: guard(do_the_locking_dance(mutex))
{
}
};
and then create a local variable
the_locking_dance guard(mutex_);
to acquire and hold on to your lock. This will also automatically release the lock upon exit from a block.
Apart from all that, note that what you're doing here is, most likely, not a good idea in general. The real question is: why are there so many different methods that all need to be protected by the same mutex to begin with? Do you really have to support an arbitrary number of threads you know nothing about, which arbitrarily may do arbitrary things with the same device object at arbitrary times in arbitrary order? If not, then why are you building your Device abstraction to support this use case? Is there really no better interface that you could design for your application scenario, knowing about what it actually is the threads are supposed to be doing. Do you really have to do such fine-grained locking? Consider how inefficient it is with your current abstraction to, e.g., call multiple device functions in a row as that requires constantly locking and unlocking and locking and unlocking this mutex again and again all over the place…
All that being said, there may be a way to improve the locking frequency while, at the same time, addressing your original question:
I'm wondering if there is a C++ construct or design pattern or paradigm which can be used to "group" these functions in such a way that the mutex_.try_lock() call is "implicit" for all functions in the group.
You could group these functions by exposing them not as methods of a Device object directly, but as methods of yet another lock guard type, for example
class Device
{
…
void DeviceFunction1();
void DeviceFunction2();
void DeviceFunction3();
void DeviceFunction4();
public:
class DeviceFunctionSet1
{
Device& device;
the_locking_dance guard;
public:
DeviceFunctionSet1(Device& device)
: device(device), guard(device.mutex_)
{
}
void DeviceFunction1() { device.DeviceFunction1(); }
void DeviceFunction2() { device.DeviceFunction2(); }
};
class DeviceFunctionSet2
{
Device& device;
the_locking_dance guard;
public:
DeviceFunctionSet2(Device& device)
: device(device), guard(device.mutex_)
{
}
void DeviceFunction3() { device.DeviceFunction4(); }
void DeviceFunction4() { device.DeviceFunction3(); }
};
};
Now, to get access to the methods of your device within a given block scope, you first acquire the respective DeviceFunctionSet and then you can call the methods:
{
DeviceFunctionSet1 dev(my_device);
dev.DeviceFunction1();
dev.DeviceFunction2();
}
The nice thing about this is that the locking happens once for an entire group of functions (which will, hopefully, somewhat logically belong together as a group of functions used to achieve a particular task with your Device) automatically and you can also never forget to unlock the mutex…
Even with this, however, the most important thing is to not just build a generic "thread-safe Device". These things are usually neither efficient nor really useful. Build an abstraction that reflects the way multiple threads are supposed to cooperate using a Device in your particular application. Everything else is second to that. But without knowing anything about what your application actually is, there's not really anything more that could be said to that…
I tried searching within questions dedicated to design patterns/data exchange/classes design, to no avail.
I am specifically programming in c++, but being this mainly a design problem, I think is quite a general one.
What I am trying to do is designing the data exchange between at least two classes, could be more,
as follows:
One class reads images from disk and shares them
Arbitrary number of classes (0+) read and process these images independently
The sharing class should not be constrained to the presence of consumer classes.
Not being an expert, only options I could think of are either publish-subscribe machinery or using a shared memory.
What are the possible solutions for such a problem, and their pros and cons?
Thank you in advance
You could implement it as a classic producer-consumer pattern. You did not mention whether producers can work from different threads, but I will assume multi-threading capability to make this solution more flexible.
// Not important what this actually is.
class Image
{ };
using ImagePtr = std::shared_ptr<Image>;
// Shared queue which stores currently available images and
// encapsulates synchronization details.
class ImageQueue
{
private:
std::queue<ImagePtr> m_images;
std::mutex m_mutex;
std::condition_variable m_cond;
public:
void PostImage(std::shared_ptr<Image> image)
{
// Lock the queue, push image, notify single thread.
std::unique_lock<std::mutex> lock(m_mutex);
m_images.push(image);
m_cond.notify_one();
}
ImagePtr WaitForImage()
{
// Lock the queue, wait if empty, fetch image and return it.
std::unique_lock<std::mutex> lock(m_mutex);
if (m_images.empty())
{
m_cond.wait(lock, [&m_images]() -> bool { return !m_images.empty(); });
}
assert (!m_images.empty());
auto nextImage = m_images.front();
m_images.pop();
return nextImage;
}
};
// Image producer class, loads images and posts them into the queue.
class ImageProducer
{
private:
ImageQueue* m_queue;
public:
void LoadImage(const char* file)
{
auto image = loadAndInitializeImageObject(file);
m_queue->PostImage(image);
}
};
// Image consumer class, fetches images and processes them.
class ImageConsumer
{
private:
ImageQueue* m_queue;
public:
void ProcessImage()
{
auto image = m_queue->WaitForImage();
processImage(image);
}
};
This a very, very beta-version concept, but it should give you an overview. Some notes:
There should be, of course, a single queue instance. It could be instantiated independently and passed to both classes as a constructor argument (via pointer or reference), but it also could be a member of ImageProducer class which could provide a public accessor to obtain the pointer/reference to it - the choice depends on particular needs.
Currently, the logic does not include clear point when processing should end. Queue could have an additional bool flag (e.g. m_processingActive, possibly wrapped in std::atomic<>). This flag would be initialized to true during construction and, after last image is produced, changed to false by the producer. Consumers would end waiting for images when queue becomes inactive.
There are probably some additional improvements, some things may be done differently and, possibly, better. But this basic concept is a quite good starting point (I hope).
Of course, you are not limited to a single ImageConsumer class. Actual processing function (processImage in my code) could be a virtual function, which is implemented in specialized classes.
Publish-subscribe is a very generic design pattern. One way to implement it is using shared memory, but doesn't work very well over a network.
I'm going to assume that you want to do this in-process, multi-threaded.
Since the data seems to be fairly large, but static you should not put the images in the sharing mechanism, but rather allocate it and pass around pointer to the allocated memory. You can clean it up at the end or if you're not sure when the consumers are done with it, use a std::shared_ptr. You can also pass around the actual image data but that would cause it to be copied multiple times. Might be ok if it's small.
Now to implement the published-subscriber mechanism in a thread-safe way is a bit hard and easy to mess up. I would suggest using a library (boost::signals2 seems recommended).
I'm running into a mild conundrum concerning thread safety for my game loop. What I have below is 3 threads (including the main) that are meant to work together. One for event managing (main thread), one for logic, and one for the rendering. All 3 of these threads exist within their own class, as you can see below. In basic testing the structure works without problems. This system uses SFML and renders with OpenGL.
int main(){
Gamestate gs;
EventManager em(&gs);
LogicManager lm(&gs);
Renderer renderer(&gs);
lm.start();
renderer.start();
em.eventLoop();
return 0;
}
However, as you may have noticed I have a "Gamestate" class that is meant to act as a container of all the resources that need to be shared between the threads (mostly with LogicManager as a writer and Renderer as a reader. EventManager is mostly just for window events). My questions are: (1 and 2 being the most important)
1) Is this a good way of going about things? Meaning is having a "global" Gamestate class a good idea to use? Is there a better way of going about it?
2) My intention was to have Gamestate have mutexes in the getters/setters, except that doesn't work for reading because I can't return the object while it's still locked, which means I'd have to put synchronization outside of the getters/setters and make the mutexes public. It also means I'd have a bloody ton of mutexes for all the different resources. What is the most elegant way of going about this problem?
3) I have all of the threads accessing "bool run" to check if to continue their loops
while(gs->run){
....
}
run gets set to false if I receive a quit message in the EventManager. Do I need to synchronize that variable at all? Would I set it to volatile?
4) Does constantly dereferencing pointers and such have an impact on performance? eg gs->objects->entitylist.at(2)->move(); Do all those '->' and '.' cause any major slowdown?
Global state
1) Is this a good way of going about things? Meaning is having a "global" Gamestate class a good idea to use? Is there a better way of going about it?
For a game, as opposed to some reusable piece of code, I'd say a global state is good enough. You might even avoid passing gamestate pointers around, and really make it a global variable instead.
Synchronization
2) My intention was to have Gamestate have mutexes in the getters/setters, except that doesn't work for reading because I can't return the object while it's still locked, which means I'd have to put synchronization outside of the getters/setters and make the mutexes public. It also means I'd have a bloody ton of mutexes for all the different resources. What is the most elegant way of going about this problem?
I'd try to think of this in terms of transactions. Wrapping every single state change into its own mutex locking code will not only impact performance, but might lead to actually incorrect behaviour if the code gets one state element, performs some computation on it and sets the value later on, while some other code modified the same element in between. So I'd try to structure LogicManager and Renderer in such ways that all the interaction with the Gamestate occurs bundled in a few places. For the duration of that interaction, the thread should hold a mutex on the state.
If you want to enforce the use of mutexes, then you can create some construct where you have at least two classes. Let's call them GameStateData and GameStateAccess. GameStateData would contain all the state, but without providing public access to it. GameStateAccess would be a friend of GameStateData and provide access to its private data. The constructor of GameStateAccess would take a reference or pointer to the GameStateData and would lock the mutex for that data. The destructor would free the mutex. That way, your code to manipulate the state would simply be written as a block where a GameStateAccess object is in scope.
There is still a loophole, though: In cases where objects returned from this GameStateAccess class are pointers or references to mutable objects, then this setup won't keep your code from carrying such a pointer out of the scope protected by the mutex. To prevent this, either take care about how you write things, or use some custom pointer-like template class which can be cleared once the GameStateAccess goes out of scope, or make sure you only pass things by value not reference.
Example
Using C++11, the above idea for lock management could be implemented as follows:
class GameStateData {
private:
std::mutex _mtx;
int _val;
friend class GameStateAccess;
};
GameStateData global_state;
class GameStateAccess {
private:
GameStateData& _data;
std::lock_guard<std::mutex> _lock;
public:
GameStateAccess(GameStateData& data)
: _data(data), _lock(data._mtx) {}
int getValue() const { return _data._val; }
void setValue(int val) { _data._val = val; }
};
void LogicManager::performStateUpdate {
int valueIncrement = computeValueIncrement(); // No lock for this computation
{ GameStateAccess gs(global_state); // Lock will be held during this scope
int oldValue = gs.getValue();
int newValue = oldValue + valueIncrement;
gs.setValue(newValue); // still in the same transaction
} // free lock on global state
cleanup(); // No lock held here either
}
Loop termination indicator
3) I have all of the threads accessing "bool run" to check if to continue their loops
while(gs->run){
....
}
run gets set to false if I receive a quit message in the EventManager. Do I need to synchronize that variable at all? Would I set it to volatile?
For this application, a volatile but otherwise unsynchronized variable should be fine. You have to declare it volatile in order to prevent the compiler from generating code which caches that value, thus hiding a modification by another thread.
As an alternative, you might want to use a std::atomic variable for this.
Pointer indirection overhead
4) Does constantly dereferencing pointers and such have an impact on performance? eg gs->objects->entitylist.at(2)->move(); Do all those -> and . cause any major slowdown?
It depends on the alternatives. In many cases, the compiler will be able to keep the value of e.g. gs->objects->entitylist.at(2) in the above code, if it is used repeatedly, and won't have to compute it over and over again. In general I would consider the performance penalty due to all this pointer indirection to be of minor concern, but that is hard to tell for sure.
Is it a good way of going about things? (class Gamestate)
1) Is this a good way of going about things?
Yes.
Meaning is having a "global" Gamestate class a good idea to use?
Yes, if the getter/setter are thread-safe.
Is there a better way of going about it?
No. The data is necessary for both game logic and representation. You could remove the global gamestate if you put it in a sub-routine, but this would only transport your problem to another function. A global Gamestate will also enable you to safe the current state very easily.
Mutex and getters/setters
2) My intention was to have Gamestate have mutexes in the getters/setters [...]. What is the most elegant way of going about this problem?
This is called reader/writer problem. You don't need public mutexes for this. Just keep in mind that you can have many readers, but only one writer. You could implement a queue for the readers/writers and block additional readers until the writer has finished.
while(gs->run)
Do I need to synchronize that variable at all?
Whenever a non-synchronized access of a variable could result in a unknown state, it should be synchronized. So if run will be set to false immediately after the rendering engine started the next iteration and the Gamestate has been destroyed, it will result in a mess. However, if the gs->run is only an indicator whether the loop should continue, it is safe.
Keep in mind that both logic and rendering engine should be stopped at the same time. If you can't shutdown both at the same time stop the rendering engine first in order to prevent a freeze.
Dereferencing pointers
4) Does constantly dereferencing pointers and such have an impact on performance?
There are two rules of optimization:
Do not optimize
Do not optimize yet.
The compiler will probably take care of this problem. You, as a programmer, should use the version which is most readable for you.
I have a C++ class with many instances, and I want to make my application thread safe.
This class has a member and a function that handles it, for example:
class MyCls {
int x;
void f() { x++; }
};
I need to protect this member, so as far as I see it I have 2 options:
Add a global Critical Section and
enter it before touching this member.
Add a Critical Section to the class
so each instance will protect its own member.
Both solutions are a huge overkills:
Two different instances should not be sync at all.
The OS should handle millions of Critical Sections, where there are actually very few collisions.
Is there another solution or multithreading design patters I can use?
Not sure, but I think the problem might be solved by using Software transactional memory mechanism. There's a bunch of implementations for C++.
As for your first concern, each instance should have a member mutex to provide a separate critical section for each.
As for the second, I'm sure that most pthread implementations use a futex implementation for their mutexes. This means that they're pretty fast when there is no contention and only require OS intervention when there is a contention.
If you don't want to use locks or critical sections, then the simplest solution is not to keep the state in the object itself. If you change your class like the following, it will be thread-safe:
// Class has no state, only operations on data. So it
// is thread-safe by nature.
class MyCls
{
int foo(int x = 0)
{
return ++x;
}
};
// Usage
MyCls obj;
int x = obj.foo(); // x = 1
x = obj.foo(x); // x = 2
If you really only need to increment that member (or similar simple arithmetic), you just need atomic operations.
Most (all?) modern CPU support them
with native instructions.
I don't know about other compilers,
but those from the gcc family have
them as builtins.
Unfortunately there seems not to be a standardized interface to these, but the upcoming C standard (C1x) will have them.
I have a server listening on a port for request. When the request comes in, it is dispatched to a singleton class Singleton. This Singleton class has a data structure RootData.
class Singleton {
void process();
void refresh();
private:
RootData mRootData;
}
In the class there are two functions: process: Work with the mRootData to do some processing and refresh: called periodically from another thread to refresh the mRootData with the latest changes from Database.
It is required that the access to mRootData be gaurded by Mutex.
I have the following questions:
1] If the class is a singleton and mRootData is inside that class, is the Mutex gaurd really necessary?
I know it is necessary for conflict between refresh/process. But from the server, i think there will be only one call to process happening at any give time ( coz the class is Singleton) Please correct me if my understanding is wrong.
2] Should i protect the i) data structure OR ii) function accessing the data structure. E.g.
i) const RootData& GetRootData()
{
ACE_Read_Guard guard(m_oMutexReadWriteLock);
return mRootData;
// Mutex is released when this function returns
}
// Similarly Write lock for SetRootData()
ii) void process()
{
ACE_Read_Guard guard(m_oMutexReadWriteLock);
// use mRootData and do processing
// GetRootData() and SetRootData() wont be mutex protected.
// Mutex is released when this function returns
}
3] If the answer to above is i) should i return by reference or by object?
Please explain in either case.
Thanks in advance.
1] If the class is a singleton and mRootData is inside that class, is the Mutex gaurd really necessary?
Yes it is, since one thread may call process() while another is calling refresh().
2] Should i protect the i) data structure OR ii) function accessing the data structure.
Mutex is meant to protect a common code path, i.e. (part of) the function accessing the shared data. And it is easiest to use when locking and releasing happens within the same code block. Putting them into different methods is almost an open invitation for deadlocks, since it is up to the caller to ensure that every lock is properly released.
Update: if GetRootData and SetRootData are public functions too, there is not much point to guard them with mutexes in their current form. The problem is, you are publishing a reference to the shared data, after which it is completely out of your control what and when the callers may do with it. 100 callers from 100 different threads may store a reference to mRootData and decide to modify it at the same time! Similarly, after calling SetRootData the caller may retain the reference to the root data, and access it anytime, without you even noticing (except eventually from a data corruption or deadlock...).
You have the following options (apart from praying that the clients be nice and don't do nasty things to your poor singleton ;-)
create a deep copy of mRootData both in the getter and the setter. This keeps the data confined to the singleton, where it can be guarded with locks. OTOH callers of GetRootData get a snapshot of the data, and subsequent changes are not visible to them - this may or may not be acceptable to you.
rewrite RootData to make it thread safe, then the singleton needs to care no more about thread safety (in its current setup - if it has other data members, the picture may be different).
Update2:
or remove the getter and setter altogether (possibly together with moving data processing methods from other classes into the singleton, where these can be properly guarded by mutexes). This would be the simplest and safest, unless you absolutely need other parties to access mRootData directly.
1.) Yes, the mutex is necessary. Although there is only one instance of the class in existence at any one time, multiple threads could still call process() on that instance at the same time (unless you design your app so that never happens).
2.) Anytime you use the value you should protect it with the mutex.
However, you don't mention a GetRootData and SetRootData in your class declaration above. Are these private (used only inside the class to access the data) or public (to allow other code to access the data directly)?
If you need to provide outside access to the data by making the GetRootData() function public, then you would need to return a copy, or your callers could then store a reference and manipulate the data after the lock has been released. Of course, then changes they made to the data wouldn't be reflected inside the singleton, which might not be what you want.