Это безопасно для всех потоков? - PullRequest
2 голосов
/ 28 июня 2010

У меня есть код, который выглядит так:

Тема 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 ]

4 голосов
/ 28 июня 2010

Это не потокобезопасно.

2 голосов
/ 28 июня 2010

Это не потокобезопасно.Если поток 1 выполняется до того, как поток 0 создаст объект, то вы получите доступ к NULL-указателю в потоке 1. (Предполагается, что m_myclass инициализируется в NULL в конструкторе)

Другой момент:

CMyClass::MySecondThreadFunc(MyOtherClass& myclass) 

myclass объект является общим объектом, и любые операции из разных потоков могут создавать проблемы.Если нет общего статического члена, локальная копия должна работать здесь для обеспечения безопасности потока.

0 голосов
/ 28 июня 2010

Если вы вызываете CMyClass::SomeFunc только до того, как будет создан второй поток, условие гонки не возникает.

В противном случае, это в основном та же проблема, которая препятствует работе двойной проверки блокировки: указательприсваивается m_myclass до фактического создания объекта, и затем поток использует неструктурированный (или частично созданный) объект.

0 голосов
/ 28 июня 2010

Вы можете создать новый CMyOtherThreadSafeClass, который состоит из двух членов CMyOtherClass *m_myclass и CRITICAL_SECTION cs.Вы должны InitializeCriticalSection или лучше с InitializeCriticalSectionAndSpinCount функцией в конструкторе CMyOtherThreadSafeClass и использовать EnterCriticalSection и LeaveCriticalSection (см. http://msdn.microsoft.com/en-us/library/aa910712.aspx и http://msdn.microsoft.com/en-us/library/ms686908.aspx) везде, если вам нужен доступ CMyOtherClass *m_myclassчлен (чтение или изменение, выделение или освобождение).

Вы можете включить метод в CMyOtherThreadSafeClass, чтобы упростить использование EnterCriticalSection и LeaveCriticalSection. Если все потоки вашей программы будут использовать EnterCriticalSection и LeaveCriticalSection тогда ваша программа будет поточно-ориентированной.

0 голосов
/ 28 июня 2010

Это не потокобезопасно, потому что оба потока обращаются к одному и тому же биту памяти.

Пока ваш код стоит, пока поток 0 выделяет память до запуска потока 1, у вас не должно быть проблем, потому что поток 0 ничего не делает, кроме выделения. Если вы измените код потока 0, чтобы он начал изменять экземпляр класса, вы начнете сталкиваться с проблемами.

[Редактировать] Удален мой пример того, что я думал, должно быть потокобезопасным. Здесь есть еще один пост на SO, который спрашивает , считается ли изменение указателя атомарным действием , которое стоит прочитать.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...