Моя идея - запустить несколько операций асинхронно; Я могу гарантировать, что две операции никогда не будут выполняться одновременно, но я не могу гарантировать, что они будут работать в одном потоке/ЦП, как и другие.Требуется блокировка, когда только один поток получает доступ к значению за раз?
// Example code
int myValue = 0;
ThreadPool.QueueUserWorkItem(state => {
myValue++;
ThreadPool.QueueUserWorkItem(state2 => {
Console.WriteLine(myValue);
});
});
Гарантирует ли выход быть 1
даже без блокировки?
Возможно, требуется позвонить Thread.MemoryBarrier()
до Console.WriteLine(myValue)
?
Или возможно myValue
должно быть сделано volatile
?
Я не очень привык к многопоточному программированию без блокировки, надеюсь, кто-то сможет решить мои сомнения.
Спасибо!
EDIT:
Что делать, если я решу использовать блокировку? Является ли этот код гарантией вывода 1
?
Если да, то почему? Не удалось компилятору сохранить myValue
в регистре CPU?
У меня никогда не было проблем с таким кодом, но я только запускал свои программы на процессорах x86 и x64. Что относительно MONO, ARM и других «эзотерических» платформ?
// Example code
object lockMe = new object();
int myValue = 0;
ThreadPool.QueueUserWorkItem(state => {
lock(lockMe) {
myValue++;
}
ThreadPool.QueueUserWorkItem(state2 => {
lock(lockMe) {
Console.WriteLine(myValue);
}
});
});
Еще раз спасибо!
'Console.WriteLine (myValue);' всегда будет печатать '1'. Но имейте в виду, что он не гарантирует, что 'myValue' уже будет увеличен после выполнения' ThreadPool.QueueUserWorkItem (...); ' – nozzleman
To" Или, может быть, 'myValue' должен быть сделан' volatile'? " - http://stackoverflow.com/a/17530556/2026276 – Bauss
@nozzleman Могу ли я спросить, как можно гарантировать, что вторая операция ('Console.WriteLine') увидит обновленную версию' myValue'? Может ли 'myValue' не кэшироваться в регистре CPU, который выполнил первую операцию (' myValue ++ ')? Простите мою неопределенность. –