Товарищи, подскажите пожалуйста, является ли следующий код thread-safe:
class A
{
private int _something;
public void Foo()
{
_something = 1;
Thread thread = new Thread(Bar);
thread.Start();
thread.Join();
Assert(_something == 2);
}
private void Bar()
{
Assert(_something == 1);
_something = 2;
}
}
Другими словами, происходит ли синхронизация памяти перед стартом нового потока, и после его завершения, а так же может ли компилятор поменять местами Thread.Start/Thread.Join с другими действиями.
В джава 1.5 такие гарантии имеют место быть (т.е. все будет работать как надо), пол-дня гуглил и читал мсдн — ни слова не нашел про то, как оно работает в C#. Может кто-нибудь дать ссылку, где про это написано?
Если это важно, речь идет о .NET 2.0
Здравствуйте, Ушастый Ёж
УЁ>Товарищи, подскажите пожалуйста, является ли следующий код thread-safe:
Да, будет, если код будет именно таким (ровно 2 потока и т.п.).
Как вариант — используйте Thread.Interlocked... методы. Или можно сделать private volatile int _something . Или используйте lock/Monitor. Или вызывайте MemoryBarrier() явно.
На самом деле Interlocked достаточно. А вместо Join лучше использовать Begin/EndInvoke или WaitHandle.
УЁ>В джава 1.5 такие гарантии имеют место быть (т.е. все будет работать как надо), пол-дня гуглил и читал мсдн — ни слова не нашел про то, как оно работает в C#. Может кто-нибудь дать ссылку, где про это написано?
Слегка расписано в рихтере. Ещё —
http://rsdn.ru/article/dotnet/CSThreading1.xmlАвтор(ы): Joseph Albahari
Дата: 24.03.2007
Подробно рассматривается работа с потоками — запуск, завершение, прерывание, блокировки, синхронизация, контексты синхронизации, особенности взаимодействия с апартаментами, а также потоковые возможности .NET — потоковые таймеры, пулы потоков, BackgroundWorker, асинхронные методы и делегаты.
В статье использован материал из книги Joseph Albahari, Ben Albahari "C# 3.0 in a Nutshell" — http://www.oreilly.com/catalog/9780596527570/
http://www.albahari.com/threading/
http://blogs.msdn.com/brada/archive/2004/05/12/volatile-and-memorybarrier.aspx и ссылки оттуда
(например
http://msdn.microsoft.com/en-us/magazine/cc163715.aspx)
Сделайте так:
private volatile int _something;
Можно через Interlocked, но в данном случае это лишнее.