c#线程在第二个线程上崩溃,不确定如何修复
本文关键字:线程 不确定 何修复 第二个 崩溃 | 更新日期: 2023-09-27 17:49:45
只是为了好玩,我创建了一个mandelbrot程序。我现在试图通过将图像分成两个左/右部分由两个线程处理,使其多线程。然而,应用程序一启动就崩溃了(尽管根据我的控制台输出,第一个线程在崩溃后继续运行,但第二个线程从未启动),我不确定该怎么办。
崩溃是在this.output[x][y] = this.calculate_pixel_rgb(x, y);
行,说我错过了一个对象引用,我不明白,因为它适用于第一个线程。
public void compute_all()
{
this.setcolors(); this.zoom_multiplier = (4 / this.zoom / this.resolution);
Thread thread1 = new Thread(new ParameterizedThreadStart(computation_thread)); thread1.Start(new double[] { 0, 0.5 });
Thread thread2 = new Thread(new ParameterizedThreadStart(computation_thread)); thread2.Start(new double[] { 0.5, 1 });
thread1.Join(); thread2.Join();
}
public void computation_thread(object threadinfo)
{
double[] parameters = (double[])threadinfo;
this.output = new int[this.resolution][][];
for (int x = (int)(this.resolution * parameters[0]); x < (int)(this.resolution * parameters[1]); x++)
{
this.output[x] = new int[this.resolution][];
for (int y = 0; y < this.resolution; y++)
{
this.output[x][y] = this.calculate_pixel_rgb(x, y);
this.pixels_completed++;
}
}
}
您的两个线程正在操作相同的输出缓冲区,相互覆盖。如果可能的话,不要在线程之间共享内存;它只会带来悲伤。
如果本练习的目的是学习如何操作原始线程,那么请退一步并研究为什么跨两个线程共享内存是一个坏主意。
如果这个练习的重点是并行计算分形,那么忘记操作原始线程。学习如何使用任务并行库会更好。
线程在逻辑上是工作者,谁想要管理一堆工作者呢?TPL鼓励您将并行看作是对可以并行完成的任务的操作。让TPL负责计算分配给任务的工人数量。
代码中的问题是多次初始化this.output
(每个线程一次)。
您的两个线程都使用相同的this
,当第一个线程初始化this.output
的列时,第二个线程重新初始化它,并且第一个线程丢失其分配的内存。
因此,this.output[x]
将不再存在于第一个线程中(missing an object reference
例外)。
这也解释了为什么你的代码只用一个线程就可以完美地运行。
你的逻辑似乎很可疑。
但如果你认为这是正确的,重置this.output
数据是必要的,在每个线程,然后做以下操作:
- 创建临时数组
- 更改
[x][y]
为[x,y] - 将
[][]
更改为[,]
- 设置
this.output
前先应用lock