1

我正在编写一个程序,根据用户提供的某些条件显示 mandelbrot 集。由于计算需要很长时间(超过 500 毫秒),我决定使用多个线程。没有任何以前的经验,我已经设法通过使用 System.Threading.Tasks 类来做到这一点,它工作得很好。我唯一不喜欢的是,每次生成 mandelbrot 时,都会创建线程然后销毁

这是它如何工作的一个例子。每次调用该方法时,它都会创建线程(任务)。

for (int i = 0; i < maxThreads; i++) {
    int a = i;
    tasks[a] = Task.Factory.StartNew(() => generateSector(a));
}

我真的不知道这会如何影响性能,但看起来创建和销毁线程很耗时,而且让线程准备好并等待触发消息会更有效率,当它们完成后返回那种等待状态。可能下面的示例代码有助于理解这个想法。

for (int i = 0; i < maxThreads; i++)
    tasks[i].sendMessage("Start"); // Tells the running thread to begin its work

因此,每个线程都会执行一个无限循环,在其中等待直到需要它们进行计算。然后,它将继续等待。像这样的东西:

// Into the method that a thread executes
while(true) {
    Wait(); // Waits for the start signal
    calculate(); // Do some calculations
}   // Go back to waiting

这样会更有效率吗?有没有办法做到这一点?

4

3 回答 3

4

保持您的代码不变。

1)任务使用ThreadPool线程,所以没有问题

2)“我真的不知道这会如何影响性能” - 这是你应该开始的地方。测量前切勿优化。你有性能问题吗?你的代码运行缓慢吗?我想没有,所以你不应该被打扰。

于 2013-09-24T13:58:17.720 回答
1

使用 时Task.Factory.StartNew(...)不一定要创建和销毁线程。任务库使用 aThreadPool来执行此操作,因此您不需要自己管理它,就像您自己创建new Thread()s一样。

于 2013-09-24T13:58:32.040 回答
0

听起来您正在尝试使用一组线程并设置一个系统来调度工作以在这些线程上运行。这是一个好主意,但事实上,它内置在 .NET 框架中,而且您不需要自己构建它。这实际上正是 Tasks 的用途。

任务是对由 .NET 运行时管理的线程池的相对轻量级的抽象。线程是一个相对较重的操作系统结构,并且在线程之间启动、停止和上下文切换有些昂贵。创建任务时,它会安排该任务在池中的下一个可用线程上执行,并且 .NET 运行时将根据是否有工作排队并等待线程来自动增加和减少池的大小执行。如果需要,您可以自定义最小最大线程数,但通常这不是必需的。

因此,通过简单地创建在单个工作单元的生命周期中存在的短期任务,它们已经让您的工作在实际线程的托管集合上运行。

于 2019-03-12T14:11:11.270 回答