I'm working with C++ and MFC to create an application that will pull information from Bloomberg in real time. Bloomberg API has a subscription class that will "subscribe" to updates from Bloomberg and push them to my PC in real time, so I need to run an eventloop in a thread to process the Bloomberg data.
In order to save bandwidth, I want to use a dictionary to map the bloomberg ticker, to its last price, so instead of getting multiple results for the same ticker (i.e. I have the same ticker in multiple times), the program will do a lookup in the dictionary. That way, I only have to subscribe to distinct tickers.
I have not worked with multithreading before and I've been reading the documentation in MSDN, but I'm having a lot of trouble understanding what I need to do.
Based on my understanding, I need to create a worker thread using AfxBeginThread(), and pass in a pointer to an instance of the dictionary. The worker thread will update the dictionary while the rest of my program runs.
Is this dictionary locked by the thread? Can I safely access it while its being updated?
Can I just leave the thread running in the background until the program terminates? Do I need to explicitly kill the thread when I terminate the program or will it be done automatically?
Does this sound right, or am I missing something fundamental?
So I've created a CMap(CString,LPCSTR,double, double) to store the tickers and pricing. I pass a pointer to the CMap through LPVOID and the CMap gets updated in real-time. This is all working now. I can lookup the variables within the CMap and get real-time pricing.
However, right now, it's not "thread-safe". There's only one thread that ever writes to the CMap, and everything else is just reading the data in the CMap, so for now, it's not a big deal.
However, in the interest of learning good programming practices, I should use a CEvent when writing to the CMap? The CEvent should be passed into the thread? I'm not sure how this is implemented. I did a quick google search, and I didn't find anything I understood on how to lock and unlock the variable within the thread.
Any objects that are not specifically designed to be thread safe are not so. Therefore you will need some mutex objects protecting the access of your "dictionary":
// for example, HINT CCriticalSection, or CSemaphore
mutex.lock();
dictionary.add(...);
mutex.unlock();
While the documentation would suggest a CSemaphore
in the above case, CCriticalSection
is (in my opinion) easier to understand for a beginner.
Threads that your application starts should be stopped by your application, yes. You can do this by signaling the thread that the work is complete:
// for example, HINT CEvent
while(!stopped)
{
do_work();
}
And set the stopped event at application exit.
For starters, have a read through here. Honestly, though these are pretty basic questions, so be prepared to really spend time learning this stuff well. If writing appropriate multithreading code was easy, everyone would do it.
As for the specific synchronization classes I mentioned, they are documented here.