1

楽しみのために、マンデルブロー プログラムを作成しました。現在、画像を左右の 2 つの部分に分割して 2 つのスレッドで処理することにより、マルチスレッド化を試みています。ただし、アプリケーションは起動するとすぐにクラッシュし (コンソール出力に基づくと、クラッシュ後も最初のスレッドは続行されますが、2 番目のスレッドは開始されません)、どうすればよいかわかりません。

クラッシュは次の行で発生し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

Your two threads are manipulating the same output buffer, overwriting each other. Don't share memory between threads if you can possibly avoid it; all it causes is grief.

If the point of this exercise is to learn how to manipulate raw threads then take a step back and study why sharing memory across two threads is a bad idea.

If the point of this exercise is to parallelize the computation of a fractal then forget about manipulating raw threads. You will do much better to learn how to use the Task Parallel Library.

Threads are logically workers, and who wants to manage a bunch of workers? The TPL encourages you to see parallization as the manipulation of tasks that can be done in parallel. Let the TPL take care of figuring out how many workers to assign to your tasks.

于 2012-12-29T04:19:21.880 に答える
1

コードの問題は、this.output複数回 (スレッドごとに 1 回) 初期化することです。

両方のスレッドが同じものを使用しthis、最初のスレッドthis.outputが の列を初期化すると、2 番目のスレッドがそれを再初期化し、最初のスレッドは割り当てられたメモリを失います。

したがって、this.output[x]最初のスレッドにはもう存在しません (missing an object reference例外)。

これは、コードが 1 つのスレッドだけで問題なく実行される理由も説明しています。

簡単な解決策は、最初に配列全体を初期化することです。

于 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 に答える