Search code examples
c++mutexsemaphorebinary-semaphore

How to synchronise 3 processes with one semaphore?


I have received an assignment to syncronise 3 tasks with one semaphore.

First two tasks generate random number, third tasks prints its sum.

So first two tasks should execute on the beginning and third in the end. Code below so far is giving me the most close results to what I want to achieve, however it obviously gets deadlock from time to time, and I cannot figure out a way to solve this with only one semaphore :(

semaphore sem;

int var1;
int var2;

void rndo(int& var) {
    int i;
    wait(sem);
    var = random(10);
    cout << var << "\n" << endl;
    signal(sem);
}

void rndt(int& var) {
    int i;  
    wait(sem);
    var = random(10);
    cout << var << "\n" << endl;
    signal(sem);
    signal(sem);
}

void prt(){
    int sum;
    wait(sem);
    wait(sem);
    wait(sem);
    cout << var1 << "- 1 2 -  " << var2 << "\n" << endl;
    sum = var1 + var2;
    cout << sum << " - full sum" << endl;
}

main(){
    initialsem(sem, 2);
    cobegin {
        rndt(var1); rndo(var2); prt();
    }

    cout << "All processes finished" << endl;
}

Solution

  • If the printer manages to wait twice before the workers get to wait, you deadlock: the printer is stuck in the third wait and the workers in their first (only) wait.

    An obvious solution would be to start the semaphore at value 0, have the printer wait twice, and have each of the workers do nothing but post -- once each.

    pseudocode:

    main:
        initialsem(sem,0);
        /*...*/
    
    worker{1,2}:
        do_work();
        post();
    
    printer:
        wait(); wait();
        do_print();