1

只是为了好玩,我创建了一个 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++;
            }
        }
    }
4

3 回答 3

7

您的两个线程正在操作相同的输出缓冲区,相互覆盖。如果可以避免的话,不要在线程之间共享内存;它引起的只是悲伤。

如果这个练习的目的是学习如何操作原始线程,那么退后一步,研究为什么在两个线程之间共享内存是一个坏主意。

如果这个练习的目的是并行化分形的计算,那么忘记操作原始线程。您将更好地学习如何使用任务并行库

线程在逻辑上是工人,谁想管理一堆工人?TPL 鼓励您将并行化视为对可以并行完成的任务的操作。让 TPL 负责确定分配给您的任务的工人数量。

于 2012-12-29T04:19:21.880 回答
1

this.output您的代码中的问题是多次 初始化(每个线程一次)。

你的两个线程都使用相同的this,当第一个线程初始化this.output的列时,第二个线程重新初始化它,第一个线程失去其分配的内存。

因此,this.output[x]将不再存在于第一个线程中(missing an object reference异常)。

这也解释了为什么您的代码只需一个线程即可完美运行。

简单的解决方案是在一开始就初始化整个数组。

于 2012-12-29T04:21:38.103 回答
0

你的逻辑似乎很可疑。

但是,如果您认为它是正确的并且this.output在每个线程中都需要重置数据,那么请执行以下操作:

  1. 制作临时数组
  2. 更改[x][y]为 [x,y]
  3. 更改[][][,]
  4. lock在设置为之前应用this.output
于 2012-12-29T04:26:20.923 回答