代码之家  ›  专栏  ›  技术社区  ›  Brandon

让线程保持空闲或杀死它们/重新启动它们?

  •  4
  • Brandon  · 技术社区  · 15 年前

    BackgroundMagic ),而且 Start() Stop() 方法。这个类中的工作是由一个线程完成的,只是每X毫秒一个短循环。

    1. 第一次调用Start()时,初始化并使用 IsBackground 在每个循环中使用一个简单的bool标志来指示它实际上应该做什么工作,还是只是睡觉。 初始初始化后,让Stop()和Start()简单地控制bool标志。自运行时起,线程将停止并清理 IsBackground =应用程序退出时为true。
    2. ,并在Start()上再次重新创建线程,而不是将线程留在周围。

    ... 或者有没有更好/更干净的方法?

    6 回复  |  直到 15 年前
        1
  •  9
  •   Dave Markle    15 年前

    也不使用 Thread Pool!

        2
  •  2
  •   David Seiler    15 年前

    线程创建相当昂贵,因此标准的“工业强度”方法是用一个标志控制线程。对于同一个概念上的较大规模的变体,考虑线程池,例如Apache用来管理数千个线程,而不需要显式的状态或痛苦的性能命中。

    因此,在摘要中,我会投票支持您的选项1。但是如果性能不是一个问题,而且选项2代码更容易推理,那么就去吧。

        3
  •  2
  •   qid    15 年前

    互斥或信号量比简单的布尔标志更好,因为它不需要反复检查标志的状态。只需阻塞互斥量/信号量,当您希望线程运行时,释放互斥量/信号量,线程将运行一次。

        4
  •  2
  •   Nate Zaugg    6 年前

    使用一个专门的线程来完成这项工作可能是一个好主意,但如何管理它可能是一件大事。如果你只是做一个 Thread.Sleep 在检查工作之间,那就没有那么有效了,因为现在你没有什么好的理由让线程旋转。这被称为旋转锁(一种),只有当您知道您正在等待的资源将很快释放锁时才有效。最好是使用 AutoResetEvent . 这样,线程只会因为生产者线程发出有工作要做的信号而被唤醒。这样做的好处是,如果无事可做,就不会浪费CPU资源来调度线程,并且可以减少生产者和消费者之间的延迟。

    要直接回答您的问题,可以使用 bool 要优雅地关闭线程(我会将其标记为 volatile 尽管如此)。这比中止线程要好得多!

        5
  •  1
  •   Glenn    15 年前

    您还可以使用bool标志来指示线程是否应该停止。这会给你中断和停止代码。所以有两个布尔值,一个用于判断是否有功,另一个用于停止循环。

        6
  •  1
  •   Johannes Rudolph    15 年前

    我会使用bool标志,但您需要确保它被正确锁定或仅从一个线程设置。你的循环应该是这样的

    while (true)
    {
      if (shouldSleep)
     {
       Thread.Sleep(interval);
       continue;
     }
    
      doSomeWork();
    
     if (shouldCancel)
     {
       CleanUpResources();
       break;
     }
    }
    

    这确保您可以将线程发送到睡眠状态,但也可以正确终止它。如果你可以避免杀死一个线程,那么杀死它永远都不是一个好主意,因为这个线程没有机会清理任何使用过的资源。不过,你需要决定一个合适的睡眠时间间隔。它将决定线程启动所需的延迟。