Question

I have a parallel algorithm which I have some barrier issues with. Before y'all scream "search" I can say I have looked at available posts and links, and I have followed the instructions for a barrier with Monitor.Wait and Monitor.PulseAll, but my issue is that all threads except the last one created (and initiated) is reached by the PulseAll from my main thread. Here are how the basic layout of the code is:

public static object signal = new object(); //This one is located as class variable, not in the method

public void RunAlgorithm(List<City> cities){
    List<Thread> localThreads = new List<Thread>();
    object[] temp = //some parameters here
    for(int i = 0; i < numOfCitiesToCheck; i++){
        Thread newThread = new Thread((o) => DoWork(o as object[]));
        newThread.IsBackground = true; 
        newThread.Priority = ThreadPriority.AboveNormal;
        newThread.Start(temp as object);
        localThreads.Add(newThread);
    }

    //All threads initiated, now we pulse all
    lock(signal){
        Monitor.PulseAll(signal); 
    }
    int counter = 0;
    while(true){
        if(counter == localThreads.Count){ break; }
        localThreads[counter].Join();
        counter++;
    }
}

That's what done by the main thread (removed a few uneccessary pieces) and as stated before the main thread will always get stuck in the Join() on the last thread in the list. This is how the method of the threads look like:

private void DoWork(object[] arguments){
    lock(signal){
        Monitor.Wait(signal);
    }
    GoDoWork(arguments); 
}

Are there any other barriers I can use for this type of signaling? All I want is to let the main thread signal all threads at the same time so that they start at the same time. I want them to start at the same time inorder to have as close parallel as possible (I measure running time for the algorithm and a few other things). Is there any part of my barrier or code that is flawed (with the barrier I mean)? I tried running an instance with fewer threads and it still get stuck on the last one, I don't know why it is. I have confirmed by via VS debug that the last thread is sleeping (all other threads are !isAlive, while the last one isAlive = true). Any help appreciated!

Was it helpful?

Solution

I managed to solve it using the Barrier class. Many thanks to Damien_The_Unbeliever! Still can't believe I haven't heard of it before.

public Barrier barrier = new barrier(1); 

public void RunAlgorithm(List<City> cities){
    List<Thread> localThreads = new List<Thread>();
    object[] temp = //some parameters here
    for(int i = 0; i < numOfCitiesToCheck; i++){
        barrier.AddParticipant(); 
        Thread newThread = new Thread((o) => DoWork(o as object[]));
        newThread.IsBackground = true; 
        newThread.Priority = ThreadPriority.AboveNormal;
        newThread.Start(temp as object);
        localThreads.Add(newThread);
    }

    barrier.SignalAndWait(); 
    int counter = 0;
    while(true){
        if(counter == localThreads.Count){ break; }
        localThreads[counter].Join();
        counter++;
    }
}


private void DoWork(object[] arguments){
    barrier.SignalAndWait();
    GoDoWork(arguments); 
}
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top