I have a MFC class with threads launched and the threads need to modify CString members of the main class.
I hate mutex locks, so there must be a an easier way to do this.
I am thinking to use the boost.org library or atl::atomic or shared_ptr variables.
What is the best method of reading and writting the string and be thread safe?
class MyClass
{
public:
void MyClass();
static UINT MyThread(LPVOID pArg);
CString m_strInfo;
};
void MyClass::MyClass()
{
AfxBeginThread(MyThread, this);
CString strTmp=m_strInfo; // this may cause crash
}
UINT MyClass::MyThread(LPVOID pArg)
{
MyClass pClass=(MyClass*)pArd;
pClass->m_strInfo=_T("New Value"); // non thread-safe change
}
According to MSDN shared_ptr works automatically https://msdn.microsoft.com/en-us/library/bb982026.aspx
So is this a better method?
#include <memory>
class MyClass
{
public:
void MyClass();
static UINT MyThread(LPVOID pArg);
std::shared_ptr<CString> m_strInfo; // ********
};
void MyClass::MyClass()
{
AfxBeginThread(MyThread, this);
CString strTmp=m_strInfo; // this may cause crash
}
UINT MyClass::MyThread(LPVOID pArg)
{
MyClass pClass=(MyClass*)pArd;
shared_ptr<CString> newValue(new CString());
newValue->SetString(_T("New Value"));
pClass->m_strInfo=newValue; // thread-safe change?
}
You could implement some kind of lockless way to achieve that, but it depends on how you use MyClass and your thread. If your thread is processing some data and after processing it, it need to update MyClass, then consider putting your string data in some other class ex.:
then inside your MyClass:
now, the idea is that in your ie. main thread code you use m_pstrData, but you need to use atomics to store local pointer to it ie.:
once your thread finished processing data, and wants to update string, you will atomically assign
m_pstrDataForThreads
tom_pstrData
, and allocate newm_pstrDataForThreads
,The problem is with how to safely delete m_pstrData, I suppose you could use here std::shared_ptr.
In the end it looks kind of complicated and IMO not really worth the effort, at least it is hard to tell if this is really thread safe, and when code will get more complicated - it will still be thread safe. Also this is for single worker thread case, and You say you have multiple threads. Thats why critical section is a starting point, and if it is too slow then think of using lockless approach.
btw. depending on how often you string data is updated you could also think about using
PostMessage
to safely pass a pointer to new string, to your main thread.[edit]
ATOMIC_MACRO does not exists, its just a place holder to make it compile use ie. c++11 atomics, example below: