stingray-11
stingray-11

Reputation: 448

C# threading crashing on 2nd thread, unsure how to do fix

Just for fun I created a mandelbrot program. I'm now trying to make it multithreaded by splitting the image into two left/right parts to be handled by two threads. However, the application crashes as soon as it's launched (although based on my console output, the first thread continues after the crash but the second thread never starts) and I'm unsure what to do.

The crash is at the line this.output[x][y] = this.calculate_pixel_rgb(x, y); and says I'm missing an object reference, which I don't understand because it works for the first thread.

    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++;
            }
        }
    }

Upvotes: 1

Views: 1280

Answers (3)

Tilak
Tilak

Reputation: 30698

Your logic seems fishy.

But if you believe it is correct and resetting this.output data is necessary in each thread, then do the following:

  1. Make temporary array
  2. Change [x][y] to [x,y]
  3. Change [][] to [,]
  4. Apply lock before setting to this.output

Upvotes: 0

Eric Lippert
Eric Lippert

Reputation: 660128

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.

Upvotes: 7

MBZ
MBZ

Reputation: 27592

The problem in your code is initializing this.output multiple times (once for each thread).

Both of your threads use the same this and when the first thread initialized this.output's columns, the second thread re-initializes it, and the first thread loses its allocated memory.

So, this.output[x] will not be existed in the first thread anymore (missing an object reference exception).

This also explains why your code runs flawlessly with just one thread.

The easy solution is to initialize the whole array at the very beginning.

Upvotes: 1

Related Questions