- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
我有一个启动了线程的 MFC 类,线程需要修改主类的 CString 成员。
我讨厌互斥锁,所以一定有更简单的方法来做到这一点。
我正在考虑使用 boost.org 库或 atl::atomic 或 shared_ptr 变量。
读取和写入字符串并确保线程安全的最佳方法是什么?
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
}
根据 MSDN shared_ptr 自动工作 https://msdn.microsoft.com/en-us/library/bb982026.aspx
那么这是更好的方法吗?
#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?
}
最佳答案
您可以实现某种无锁方式来实现这一点,但这取决于您如何使用 MyClass 和您的线程。如果您的线程正在处理一些数据并且在处理之后需要更新 MyClass,那么请考虑将您的字符串数据放在其他类中,例如:
struct StringData {
CString m_strInfo;
};
然后在你的 MyClass 中:
class MyClass
{
public:
void MyClass();
static UINT MyThread(LPVOID pArg);
StringData* m_pstrData;
StringData* m_pstrDataForThreads;
};
现在,这个想法是在你的 ie.您使用 m_pstrData 的主线程代码,但您需要使用原子来存储指向它的本地指针,即:
void MyClass::MyClass()
{
AfxBeginThread(MyThread, this);
StringData* m_pstrDataTemp = ATOMIC_READ(m_pstrData);
if ( m_pstrDataTemp )
CString strTmp=m_pstrDataTemp->m_strInfo; // this may NOT cause crash
}
一旦您的线程完成数据处理,并想要更新字符串,您将自动分配 m_pstrDataForThreads
给 m_pstrData
,并分配新的 m_pstrDataForThreads
,
问题在于如何安全地删除 m_pstrData,我想你可以在这里使用 std::shared_ptr。
最后它看起来有点复杂而且 IMO 真的不值得付出努力,至少很难说这是否真的是线程安全的,当代码变得更复杂时 - 它仍然是线程安全的。这也是针对单工作线程的情况,你说你有多个线程。这就是为什么临界区是一个起点,如果它太慢然后考虑使用无锁方法。
顺便说一句。根据字符串数据的更新频率,您还可以考虑使用 PostMessage
将指向新字符串的指针安全地传递到主线程。
[编辑]
ATOMIC_MACRO 不存在,它只是一个使其编译使用的占位符。 c++11 原子,示例如下:
#include <atomic>
...
std::atomic<uint64_t> sharedValue(0);
sharedValue.store(123, std::memory_order_relaxed); // atomically store
uint64_t ret = sharedValue.load(std::memory_order_relaxed); // atomically read
std::cout << ret;
关于C++/MFC/ATL 线程安全字符串读/写,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/30947368/
我是一名优秀的程序员,十分优秀!