C# 多线程

发布于 2024-09-25 05:23:59 字数 731 浏览 3 评论 0原文

好的。我想让两个线程运行。当前代码:

    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
                   }
                 }
             }
     }

两者都访问同一个列表,问题是第一个线程“foo”没有释放我猜的锁;因为“bar”仅在“foo”完成后才开始。谢谢

Okay. I want to have two threads running. Current code:

    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
                   }
                 }
             }
     }

Both are accessing the same List, the problem is that the first thread "foo" is not releasing the lock i guess; because "bar" only starts when "foo" is done. Thanks

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

和我恋爱吧 2024-10-02 05:23:59

是的,这就是锁的设计原理。

lock 关键字通过获取给定对象的互斥锁、执行语句,然后释放锁来将语句块标记为临界区。

互斥是指任一时刻最多只能有一个线程持有锁。

锁定这一点是一个坏主意,不鼓励这样做。您应该创建一个私有对象并锁定它。为了解决您的问题,您可以锁定两个不同的对象。

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
       }
   }
}

但是,我建议您花一些时间来了解正在发生的事情,而不是重新排序代码行,直到它看起来可以工作在你的机器上。编写正确的多线程代码很困难。

为了停止线程,我推荐这篇文章:

Yes, that's how lock is designed to work.

The lock keyword marks a statement block as a critical section by obtaining the mutual-exclusion lock for a given object, executing a statement, and then releasing the lock.

Mutual-exclusion means that there can be at most one thread that holds the lock at any time.

Locking on this is a bad idea and is discouraged. You should create a private object and lock on that instead. To solve your problem you could lock on two different objects.

private object lockObject1 = new object();
private object lockObject2 = new object();

public void foo()
{      
    lock (lockObject1)
    {
         // ...
    }
}

public void bar()
{      
    lock (lockObject2)
    {
         // ...
    }
}

Alternatively you could reuse the same lock but move it inside the loop so that each loop has a chance to proceed:

while (stopThreads == false)
{
   foreach (var acc in myList)
   {
       lock (lockObject)
       {
           // process some stuff
       }
   }
}

However I would suggest that you spend some time to understand what is going on rather than reordering the lines of code until it appears to work on your machine. Writing correct multithreaded code is difficult.

For stopping a thread I would recommend this article:

望她远 2024-10-02 05:23:59

由于您并不是真正在问问题,因此我建议您应该阅读有关线程如何工作的教程。可以此处找到 .Net 特定指南。它的主题包括“入门”、“基本同步”、“使用线程”、“高级线程”和“并行编程”。

另外,你还锁定了“这个”。 Msdn 说:

一般来说,避免锁定公共
类型或超出代码范围的实例
控制。常见的构造lock
(this)
lock (typeof (MyType))
lock ("myLock") 违反了这一点
指导方针:

  • lock (this) 是一个问题,如果
    实例可以公开访问。

  • lock (typeof (MyType)) 是一个问题,如果
    MyType 可公开访问。

  • lock(“myLock”) 是一个问题,因为
    进程中使用的任何其他代码
    相同的字符串,将共享相同的
    锁。

最佳实践是定义一个私有的
要锁定的对象,或私有静态
对象变量保护数据公共
到所有实例。

Since you are not really asking a question, I suggest you should read a tutorial on how threading works. A .Net specific guide can be found here. It features the topics "Getting Started", "Basic Synchronization", "Using Threads", "Advanced Threading" and "Parallel Programming".

Also, you are locking on "this". The Msdn says:

In general, avoid locking on a public
type, or instances beyond your code's
control. The common constructs lock
(this)
, lock (typeof (MyType)), and
lock ("myLock") violate this
guideline:

  • lock (this) is a problem if the
    instance can be accessed publicly.

  • lock (typeof (MyType)) is a problem if
    MyType is publicly accessible.

  • lock(“myLock”) is a problem because
    any other code in the process using
    the same string, will share the same
    lock.

Best practice is to define a private
object to lock on, or a private static
object variable to protect data common
to all instances.

草莓味的萝莉 2024-10-02 05:23:59

您遇到的问题是您使用的锁非常粗糙。 Foo 和 Bad 基本上不会同时工作,因为无论谁先启动,都会在整个工作周期中停止另一个。

不过,它应该仅在将内容从列表中删除时才锁定。根据定义,Foreach 在这里不起作用。您必须建立第二个列表,并让每个线程删除顶部的项目(同时锁定),然后对其进行处理。

基本上:

  • Foreach 不起作用,因为两个线程都将运行完成列表
  • 其次,锁必须是细粒度的,因为它们仅在需要时才锁定。

在你的情况下,你锁定的 foo 只会在 foo 完成时被释放。

The problem you have is that you work with a very coarse lock. Both Foo and Bad basically do not work concurrently because whoever starts first stops the other one for the COMPLETE WORK CYCLE.

It should, though, ONLY lock WHILE IT TAKES THINGS OUT OF THE LIST. Foreach does not work here - per definition. You ahve to put up a second list and have each thread REMOVE THE TOP ITEM (while lockin), then work on it.

Basically:

  • Foreach does not work, as both threads will run through the compelte list
  • Second, locks must be granular in that they only lock while needed.

In your case, you lock in foo will only be released when foo is finished.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文