【问题标题】:Creating Threads inside recursive function在递归函数中创建线程
【发布时间】:2016-12-13 21:14:01
【问题描述】:

我有一个带有一些递归函数的应用程序,一般看起来像这样:

threads = 0;
Algorithm(array) {
    //some code...

    newArray1 = array.Take(array.Length / 2).ToArray();
    newArray2 = array.Skip(array.Length / 2).ToArray();

    ThreadStart start1 = delegate
        {
            Algorithm(newArray1);
        };

    Thread thread1 = new Thread(start1);

    ThreadStart start2 = delegate
        {
            Algorithm(newArray2);
        };

    Thread thread2 = new Thread(start2);
    thread1.Start();
    threads++;
    thread2.Start();
    threads++;
}

不管这个递归有多深,变量threads总是等于2。为什么?

【问题讨论】:

  • 因为两个线程共享同一个变量threads
  • @user3185569 所以范围对线程无关紧要?
  • 您没有将公共变量设置为Mutual exclusion section。这可能会产生一些不一致的解决方案,因此作为一种良好做法,任何共享变量都应位于互斥部分中。当你等待/加入你的线程来同步它?
  • 什么范围?它们都共享相同的变量,并且您在那里有一个竞争条件。这完全取决于您何时检查threads 的值。在启动第二个线程之前尝试Thread.Sleep(5000) 并在每个委托中打印threads 的值,您很可能会得到12 作为输出。
  • 这里面是什么类型的?我假设threads 是一个周围类型的字段,对吗?如果是的话,你能展示一下这个类型的声明吗?

标签: c# multithreading recursion


【解决方案1】:

我假设您没有等待线程完成。您需要在Algorithm 方法中添加对Thread.Join() 方法(documentation)的调用,该方法“阻塞调用线程,直到此实例表示的线程终止”(您可以为thread1thread2)。此外,您需要使用“为多个线程共享的变量提供原子操作”的Interlocked 类来增加线程数(请参阅Increment method)。

话虽如此,您应该记住,为单个任务创建新线程效率非常低(创建线程/上下文切换会产生性能开销)。相反,您应该使用 CLR 提供的线程池。如果您想了解更多关于如何使用任务并行来有效利用线程池的信息,请参阅this link

【讨论】:

  • 谢谢。还有一件事:我在函数末尾使用了thread1.Abort(); thread2.Abort();。是的,我知道这很糟糕,但我有一个问题:在调试中我只能看到两个 'ThreadAbortException' 异常,但实际上发生了 8 个递归级别!所以实际上只有 2 个线程存在。为什么?
  • 我不会依赖这个异常来找出启动了多少线程。尝试将以下代码添加到 Algorithm 方法 Console.WriteLine("Current thread id: {0}", Thread.CurrentThread.ManagedThreadId); 的开头
  • 你是否通过调用Join()来等待其他线程完成?
  • 不,我不知道。仅启动和中止它们。
  • 主线程在其他线程完成之前退出,这就是为什么您看不到其他线程向控制台报告其 ID
【解决方案2】:

是的,threads 变量是共享的。查看此链接以使用具有递归函数的线程 - How to use threads with a recursive template function

【讨论】:

  • 但是如果变量是共享的,递归性不应该增加它高于 2吗?这里可能存在锁定和竞速问题,但如果 OP 是正确的,变量 always 包含值 2,那不是很奇怪吗?
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2022-01-11
  • 1970-01-01
  • 1970-01-01
  • 2020-09-20
  • 2022-01-12
  • 2010-12-15
相关资源
最近更新 更多