【发布时间】:2014-03-19 15:11:58
【问题描述】:
我有一个示例程序,我试图在其中复制我的实际应用程序场景。有没有办法只锁定一次而不是每个循环,这实际上会降低并行循环的性能。如果我删除锁,性能就像预期但我在竞态条件下运行。我在 GetTotal 方法中有某些代码也进入竞态条件。在多个线程试图修改共享变量的情况下是否可以进行并行处理。是否有更好的方法来改善长时间运行性能
private static void Main()
{
var datetime = DateTime.Now;
int j = 0;
Parallel.ForEach(Enumerable.Range(0, 5), i =>
{
lock (SomeLockObject)
{
Console.WriteLine(j++);
GetTotal(j);
}
});
Console.WriteLine(DateTime.Now.Second - datetime.Second);
Console.ReadLine();
}
static long GetTotal(int j)
{
long total = 0;
for (int i = 1; i < 1000000000; i++) // Adjust this loop according
{ // to your computer's speed
total += i + j;
}
return total;
}
【问题讨论】:
-
这个问题中的任何内容都没有让我觉得不正确。锁定将强制竞争相同资源或试图相互协同工作的线程之间进行协调。这是您正在进行的权衡,听起来好像不需要竞争条件,因此需要锁定或其他一些编排机制。让某些东西并行运行可能并不总是让它更快地完成任务。并发总是需要审查信息流、共享资源的使用、所需的输出等。并非所有东西都很好地适合这个模型。
-
基本上:(a) 并非所有算法都可以轻松并行化,(b) 编程尽可能不锁定。是的,除了简单的演示之外,多线程编程并不完全简单。
-
我同意 Houldsworth 所说的。您锁定了每个单独的循环,因此实际上您没有获得任何性能。相反,您正在失去性能,因为现在您有六个线程获取和释放锁只是为了增加一个值。
-
您将货物分成 5 辆卡车,但它们都在同一车道上行驶。
-
你还没有问过问题。是的,锁定并行块的整个主体是一个坏主意。是的,就目前而言,如果没有某种形式的同步,您的程序将无法按您希望的方式运行。现在你的问题是什么?