C#多线程
好的。我想有两个线程在运行。当前代码:C#多线程
public void foo()
{
lock(this)
{
while (stopThreads == false)
{
foreach (var acc in myList)
{
// process some stuff
}
}
}
}
public void bar()
{
lock(this)
{
while (stopThreads == false)
{
foreach (var acc in myList)
{
// process some stuff
}
}
}
}
两者都访问相同的List,问题是第一个线程“foo”没有释放我猜的锁;因为“bar”仅在“foo”完成时才开始。谢谢
是的,这就是锁的设计工作。
锁关键字标志着一个语句块作为通过获得互斥锁定给定对象,执行语句,然后解除锁定的一个关键部分。
相互排斥意味着最多只能有一个线程在任何时间持有锁。
锁定这是一个坏主意,并且不鼓励。您应该创建一个私有对象并对其进行锁定。为了解决你的问题,你可以锁定两个不同的对象。
private object lockObject1 = new object();
private object lockObject2 = new object();
public void foo()
{
lock (lockObject1)
{
// ...
}
}
public void bar()
{
lock (lockObject2)
{
// ...
}
}
另外,您可以重复使用相同的锁,但将它的循环中,使每个环都有机会进行:
while (stopThreads == false)
{
foreach (var acc in myList)
{
lock (lockObject)
{
// process some stuff
}
}
}
不过我建议你花一些时间来了解什么是继续而不是重新排序代码行直到它看起来在你的机器上工作。编写正确的多线程代码很困难。
对于停止线程我会推荐这篇文章:
stopThreads变量怎么样,它不是线程安全的,可能是他得到了完全错误的结果。 – TalentTuner 2010-09-25 11:18:42
@saurabh:它可能会变得不稳定。或者它可以被制成一个线程安全的属性。 – 2010-09-25 11:28:49
谢谢,那工作。 – foobar 2010-09-25 14:52:32
你的问题是,你有一个非常粗糙的锁定工作。 Foo和Bad都基本不兼容,因为谁先启动就停止另一个完成工作循环。
它应该虽然只锁定,但它需要的东西出列表。根据定义,Foreach在这里不起作用。你要提出第二个清单,并让每个线程删除顶部项目(同时锁定),然后处理它。
基本上是:
- 的foreach是不行的,因为两个线程将通过compelte列表运行
- 其次,锁具必须是,他们只需要同时锁定颗粒状。
在你的情况下,你锁定foo只会在foo完成时被释放。
既然你不是真的在问一个问题,我建议你应该阅读关于线程工作原理的教程。 .Net特定指南可以是found here。它包含“入门”,“基本同步”,“使用线程”,“高级线程”和“并行编程”等主题。
另外,您正在锁定“this”。该Msdn说:
一般情况下,避免锁定在公共 类型,或超出你的代码的 控件实例。共同构建
lock (this)
,lock (typeof (MyType))
,并lock ("myLock")
违反本 方针:
lock (this)
是一个问题,如果 实例可以被公开访问。
lock (typeof (MyType))
是一个问题,如果 MyType是可公开访问。
lock(“myLock”
)是因为 使用 相同的字符串的处理的任何其他代码,将共享相同的 锁的问题。最佳做法是定义一个私人 对象锁定或私有静态 对象变量,以保护共同 所有实例的数据。
是的,bar只会在foo完成后启动,这就是锁的工作方式,您应该提供更多关于如何让代码运行的细节。 – 2010-09-25 11:24:01
读取semaphore/mutex的定义,然后移除锁定 – 2010-09-25 11:51:21