【发布时间】:2021-03-21 02:01:34
【问题描述】:
我正在尝试理解多线程,并且我有以下代码,我需要通过获得最终结果 10,000,000 来确保线程安全(通常不使用 lock 语句),但是如果您在 VS 中多次运行以下代码,您获得接近 10,000,000 的不同值但从未达到,因此我需要在不使用 lock 语句的情况下修复此代码。
using System;
using System.Threading;
namespace ConsoleApp1
{
class Program
{
private static int _counter = 0;
private static void DoCount()
{
for (int i = 0; i < 100000; i++)
{
_counter++;
}
}
static void Main(string[] args)
{
int threadsCount = 100;
Thread[] threads = new Thread[threadsCount];
//Allocate threads
for (int i = 0; i < threadsCount; i++)
threads[i] = new Thread(DoCount);
//Start threads
for (int i = 0; i < threadsCount; i++)
threads[i].Start();
//Wait for threads to finish
for (int i = 0; i < threadsCount; i++)
threads[i].Join();
//Print counter
Console.WriteLine("Counter is: {0}", _counter);
Console.ReadLine();
}
}
}
感谢您的帮助。
【问题讨论】:
-
volatile还不够,但System.Threading.Interlocked.Increment()可以。 -
无锁编程真的很难正确完成。您应该不惜一切代价避免它。
-
@Blindy 它需要 大量 的专业知识才能知道在多线程程序中何时可以并且不能真正避免锁定,此外还有使用锁定的成本这一事实,在大多数情况下,都不是问题。如果您达到无锁编程的第一个可能性非常,您的程序充满了错误,并且您不会从中获得任何好处,因为锁不会成为瓶颈。至于这个程序中的线程池不同,差异不大可能那么大,即使并行运行,出现bug的时间窗口也不是很大。
-
@Blindy 人们多久编写一次性能如此重要的“低级库”,以至于他们没有一个位数的纳秒来取出锁?这个数字不是零,但它超低。如果您认为这很容易,那么这只是告诉我您不了解它可能出错的所有方式以及使用它时需要考虑的所有事情。如果您有嵌套锁,那么这意味着您有一个非常复杂的情况,即无锁解决方案偶数可能的可能性非常低,如果是这样的话,这远非易事。
标签: c# multithreading thread-safety