【问题标题】:Starting threads and waiting for them all to finish启动线程并等待它们全部完成
【发布时间】:2011-09-07 02:11:58
【问题描述】:

我有以下一段代码 (C#):它正确吗?

Thread[] threads = new Thread[totalThread];

for (int i=0; i<totalThread; i++) {
   threads[i] = new Thread(new ThreadStart(Work));
}

sw.Start();

for (int j=0; j<num_threads; j++) {
   threads[j].Start();
}


for (int k=0; k<num_threads; k++) {
   threads[k].Join();    
}

sw.Stop();

sw 是秒表,work 是某种方法。我想使用几个线程来计时这个方法,但整个事情都冻结了(似乎它没有加入)。我需要知道我的线程处理是否良好,或者我是否搞砸了。如果是后者,很明显我的问题在于我正在调用的方法,而不是线程管理。谢谢。

【问题讨论】:

  • 一切看起来都很好。可以发一下 Work 方法的代码吗?
  • 为什么在第一个循环中使用totalThread,在接下来的两个循环中使用num_threads?无论如何,问题可能出在您的 Work 方法上,因为上面的代码应该没问题。
  • 再说一次,不知道DoSomething() 或DoSomethingElse() 长什么样,很难说。 totalOperation 有多大?另外,你可以直接说op = r.Next(2)。
  • 发布 DoSomething() 方法,或者如果它们太大,用假人替换它们。没有他们,这不是一个真正的问题。
  • @Henk 从技术上讲,我认为 OOT 会更多,并被转移到 Codereview

标签: c# multithreading


【解决方案1】:

既然你提到了冻结。尝试检查您的工作方法并寻找死锁。此外,在您的加入呼叫中添加一些超时机制。

【讨论】:

    【解决方案2】:

    它是完美的。除了num_threads/totalThread,我没有看到任何问题。请注意,如果totalThread 很大(这里的 big 是指每个 CPU 内核大于 1-2),您可能应该使用ThreadPool。

    【讨论】:

    • 我想知道 -1 的原因。没问题,就是知道。我的回答是正确的,建议是正确的。那么?
    【解决方案3】:

    您可以摆脱 .Join 循环并在每个线程中使用 ManualResetEvent。

    然后,您将等待 ManualResetEvents 全部发出信号。

    【讨论】:

    • 不确定为什么需要这样做。如果Work()方法没问题,上面的代码也没问题。
    • 到底有什么区别?
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2010-10-11
    • 1970-01-01
    • 2021-12-13
    • 1970-01-01
    • 2019-02-23
    • 2014-09-20
    • 1970-01-01
    相关资源
    最近更新 更多