Multithreaded thread-safe animation suggestions in c++
I have a timer-based animation program, which was scheduled to be run in a worker thread. The program was designed to run operationally all the time on startup. I also have an image production thread, which is responsible for image processing, and then feeds each processed image (in JPEG/PNG format) to the animation thread to take part in image looping without user intervention.
That's a typical memory-based image looping program. That is to say, all user-selected images are loaded into RAM in advance. I use a map container to manage the image sequence, declared in the format of std::map, which associates image file names of type Key with CBitmap pointers of type Data. I also use a vecter string (declared like std::vector) to keep a copy of the image file list in a sorted order corresponding to the aforesaid map key list in order to iterate each image by is sequential 开发者_开发百科number. That's may be not necessary. With regard to animaion control, the following kiosk-like operations (some accompanied with their respectve variables declarations) are allowed:bool m_bPlay; // Play forward
bool m_bPause; // Pause animation
bool m_bStop; // Stop animation
bool m_bReverse; // Play backward
bool m_bRepeat; // Repeated play when reaching to last image
DWORD m_dwFrom; // Starting image number
DWORD m_dwTo; // Ending image number
DWORD m_dwCurrent; // Current image number
DWORD m_dwFPS; // Frames per second
Where m_dwTo variable can be changed by a user through the use of a spin button embedded in a toolbar doakced on the top of the main GUI window, or increased automatically by the application each time a newly processed image added into the above-mentioned map as well as vector containers. Similarly, m_dwFrom variable can also be changed manually in the same way as m_dwTo, or reduced automatically by the application whenever one or more than one in-play images are expired on the basis of the user-defined rolling archive configuration (for example, keep images in 3 days), and at the same time, the overdue image(s) should be removed from the above-mentioned map and vector containers. The m_dwFPS variable can be changed by user at any time in the process of image looping with a drop-down list box embedded in a toolbar doakced on the top of the main GUI window.
Thank you for taking the time to read the long explanation on which I want to do. I do hope that it can help you in answering my following questions:
- In order to make m_dwFrom, m_dwTo, m_dwCurrent, and m_dwFPS thread safe, is it more efficient and performance gaining by using InterlockedExchange or InterlockedCompareExchange than the use of other locks such as CriticalSection, Mutex, and etc.?
- How to make std::map and std::vector thread safe? Use traditional locks only, or better coupled with compiler reordering barrier (for example, _ReadWriteBarrier forVisual C++) and/or CPU reordering barrier (for example, MemoryBarrier x86 and x64 CPU family)?
I'm looking forward to seeing your suggestions. Code or false code snippets are highly appreciated. Thank you in advance!
Golden LeeI might be wrong but as far as I can guess from you description I'd go with traditional locks and mutexes to make your shared vector and map aswell as your other shared variables threadsafe. It simply is the most straightforward way and your scenario does not really sound that performance intensive to justify anything more complex. I'd only touch anything more fancy if profiling shows that traditional locking becomes a performance issue!
How to make std::map and std::vector thread safe?
The common way to do that is to simply write a locking wrapper around the container functions you need access to. For instance:
class myAnimationManager{
private:
std::map<std::string, CBitmap*> m_imagesMap;
Mutex m_mutex;
public:
CBitmap * getImageByName(const std::string & _name)
{
ScopedLock l(m_mutex); //lock image map access
return m_imagesMaps[_name];
}
//...
};
The good thing about staying with standard locking primitives is not only simplicity but also portability when using boost::thread for instance.
精彩评论