C# 确保螺纹安全,无需C中的lock语句
我正在尝试理解多线程,我有以下代码,我需要确保线程安全,通常不使用lock语句,通过获得最终结果10000000,但如果在VS中多次运行以下代码,您会得到接近10000000的不同值,但从未达到它,所以我需要在不使用lock语句的情况下修复此代码C# 确保螺纹安全,无需C中的lock语句,c#,multithreading,thread-safety,C#,Multithreading,Thread Safety,我正在尝试理解多线程,我有以下代码,我需要确保线程安全,通常不使用lock语句,通过获得最终结果10000000,但如果在VS中多次运行以下代码,您会得到接近10000000的不同值,但从未达到它,所以我需要在不使用lock语句的情况下修复此代码 using System; using System.Threading; namespace ConsoleApp1 { class Program { private static int _counter = 0
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();
}
}
}
感谢您的帮助。是的,互锁函数类是实现无锁多线程同步的途径。在您的特定情况下,您希望您最好先了解线程,然后快速进入一个为您抽象复杂性的库 如果您使用Microsoft的反应式框架aka Rx-NuGet System.Reactive,并使用System.Reactive.Linq;-然后你可以这样做:
void Main()
{
var query =
from n in Observable.Range(0, 100)
from x in Observable.Start(() => DoCount())
select x;
var counter = query.Sum().Wait();
Console.WriteLine("Counter is: {0}", counter);
Console.ReadLine();
}
private int DoCount()
{
int counter = 0;
for (int i = 0; i < 100000; i++)
{
counter++;
}
return counter;
}
简单多了,结果是:计数器是:10000000您试过了吗?如果没有足够的数据,例如,volatile是不够的,但是System.Threading.Interlocked.Increment是不够的。无锁编程很难正确执行。你应该不惜一切代价避免它。@盲目地说,在多线程程序中,除了在大多数情况下使用锁的成本不是问题之外,还需要大量的专业知识才能知道什么时候可以避免锁,什么时候不能避免锁。如果您首先使用无锁编程,那么您的程序充满bug的几率非常高,并且您不会从中获得任何好处,因为锁不会成为瓶颈。对于这个程序中不同的线程池,差异不太可能那么大,即使在并行运行时,bug的时间窗口也不是很大。@Blindy,人们编写性能非常重要的低级库的频率是多少,他们没有一位数的纳秒来打开锁?数字不是零,但它是超低的。如果你认为它很容易,那么这就告诉我,你不了解它可能出错的所有方式,以及使用它时需要考虑的所有事情。如果你有嵌套锁,那么这意味着你有一个非常复杂的情况,没有锁的解决方案是可能的几率非常低,如果是的话,那就很难了。它成功了,老实说,我以前没有听说过。这意味着你是其中之一!JAJA,这是一个geekIt,在先学习较低级别后,值得尝试一下。超级谢谢你