Я столкнулся с проблемой, что у меня есть объект С# (.NET), совместно используемый некоторыми потоками. Поток может заменить объект другим. Потоки активируются из соединения TCP/IP с использованием асинхронной инфраструктуры.
Последовательность:
Потоки (ожидание соединения) -> Асинхронный обратный вызов -> Сделать что-нибудь потокобезопасное -> Доступ к общему объекту -> Сделать что-нибудь потокобезопасное.
1. Мьютекс решения:
Object sharedObject = new Object();
Mutex objectMutex = new Mutex();
void threadCallback()
{
Object newObject = new Object();
// some processing
objectMutex.lock();
// do exchange sharedObject with newObject if needed
// very little processing here
objectMutex.unlock();
// some processing
}
2. Блокировка решения
Object sharedObject = new Object();
int usingSharedObject = 0;
void threadCallback()
{
Object newObject = new Object();
// some processing
// poll until we lock
while(1 == Interlocked.Exchange(ref usingSharedObject , 1))
{
// do exchange sharedObject with newObject if needed
// very little processing here
Interlocked.Exchange(ref usingSharedObject , 0); // free lock
}
// some processing
}
Что быстрее и лучше масштабируется?
Я ожидаю, что второе решение будет быстрее, если одновременно не будет опрашиваться много потоков. Второе решение может даже засыпать в случайное время, чтобы опрос не поглощал время обработки. Первое решение кажется мне чище, если мне действительно нужно обработать много TCP/IP-соединений. Поскольку я очень мало обрабатываю в заблокированном разделе, касающемся обработки TCP/IP, возникнут ли какие-либо проблемы с масштабированием?
Как насчет создания объекта в начале функции threadCallback().
В моем опыте C++ я всегда использовал пулы памяти в такой ситуации, так как я должен использовать безопасный .NET, есть ли быстрый способ создавать новые объекты или платформа .NET хорошо работает в этой области.
С наилучшими пожеланиями,
Фридрих
Interlocked.Exchange
возвращает значение 1-го аргумента до того, как ему было присвоено новое значение, поэтому вы перейдете к обработке циклаwhile
только после того, как другой поток заявит флаг (и этот поток не сбросит флаг). - person Michael Burr   schedule 03.02.2010