跨线程这是安全的吗?

时间:2010-06-28 07:59:36

标签: c++ pointers multithreading thread-safety

我有一些看起来像这样的代码:

主题0:

CMyOtherClass *m_myclass;

CMyClass::SomeFunc(DWORD SomeParam)
{

m_myclass = new CMyOtherClass(SomeParam);

}

主题1:

CMyClass::InsideSecondThread()
{

   MySecondThreadFunc(*m_myclass);

}

CMyClass::MySecondThreadFunc(MyOtherClass& myclass)  
{

// do something with myclass variable....
// What about thread safety???  Is this not now a shared variable?
// or have we passed a copy and are we safe?
// SomeParam should be the same while in this thread, however it can be changed by Thread 0


}

所以我的问题是,如果你跨越线程传递这个m_myclass变量,这个线程是否安全?

5 个答案:

答案 0 :(得分:4)

这不是线程安全的。

答案 1 :(得分:2)

这不是线程安全的。 如果线程1在线程0创建对象之前执行,那么最终会访问线程1中的NULL指针。(假设m_myclass在构造函数中初始化为NULL)

另一点是:

CMyClass::MySecondThreadFunc(MyOtherClass& myclass) 

myclass对象是共享对象,来自不同线程的任何操作都可能产生问题。 除非有共享的静态成员,否则本地副本应该适用于线程安全。

答案 2 :(得分:0)

这不是线程安全的,因为两个线程都在访问相同的内存。

正如你的代码所代表的那样,只要线程0在线程1启动之前分配内存,那么你应该没有问题,因为线程0除了分配之外什么都不做。如果您更改了线程0代码以便它开始修改类实例,那么您将开始遇到问题。

[编辑] 删除了我认为应该是线程安全的示例。这里有另一篇关于SO的帖子,要求whether changing a pointer is considered an atomic action值得一读。

答案 3 :(得分:0)

您可以创建一个包含两个成员的新CMyOtherThreadSafeClass CMyOtherClass *m_myclassCRITICAL_SECTION csInitializeCriticalSection构造函数中的InitializeCriticalSectionAndSpinCount函数应CMyOtherThreadSafeClass或更好,并使用EnterCriticalSectionLeaveCriticalSection(请参阅http://msdn.microsoft.com/en-us/library/aa910712.aspxhttp://msdn.microsoft.com/en-us/library/ms686908.aspx )如果您需要访问CMyOtherClass *m_myclass成员(阅读或修改,分配或免费),无处不在。

您可以在CMyOtherThreadSafeClass中添加方法,以便更轻松地使用EnterCriticalSectionLeaveCriticalSection。如果程序的所有线程都使用EnterCriticalSectionLeaveCriticalSection,那么您的程序将是线程安全的。

答案 4 :(得分:0)

如果仅在创建第二个线程之前调用CMyClass::SomeFunc,则表示没有竞争条件。

否则,它基本上是防止双重检查锁定工作的相同问题:指针可以在实际构造对象之前分配给m_myclass,然后线程使用未构造的(或部分构造的)对象