Click here to Skip to main content
15,887,135 members
Please Sign up or sign in to vote.
0.00/5 (No votes)
See more:
Facing deadlock issue in below program, The same instance of below class will be passed to three different thread one is responsible for printing 0, and one for even num and other for odd.
After printing 0 1 it print killed and terminates. In case of debugger i am not able follow which thread is executing which statement, i am trying to find to find proper way to debug multithreading program. Please help i am new to multithreading like what is causing deadlock here.

Test case tried below is n = 3
output 0
1
Killed

What I have tried:

C++
#include <semaphore.h>
#include <bits/stdc++.h>
#include <thread>
using namespace std;
class ZeroEvenOdd {
private:
    int n;
    int i = 1;
    sem_t sZero, sEven, sOdd;

public:
    ZeroEvenOdd(int n) {
        this->n = n;
        sem_init(&sZero, 0, 1); // Initialized to 1 to allow the first zero to be printed.
        sem_init(&sEven, 0, 0); // Initialized to 0 to block the even thread initially.
        sem_init(&sOdd, 0, 0);  // Initialized to 0 to block the odd thread initially.
    }

    void printSem(sem_t sem){
        int value;
        sem_getvalue(&sem, &value);
        cout<<value<<endl;
    }

    // printNumber(x) outputs "x", where x is an integer.
    void zero(std::function<void(int)> printNumber) {
        if (i > n) {
            return;
        }

        sem_wait(&sZero);
        printNumber(0);

        if (i % 2 == 1) {
            sem_post(&sOdd);
        } else {
            sem_post(&sEven);
        }
    }

    void even(std::function<void(int)> printNumber) {
        if (i > n) {
            return;
        }
        cout<<"printing even sem ";
        printSem(sEven);
        cout<<endl;

        sem_wait(&sEven);
        i++;
        printNumber(i-1);
        sem_post(&sZero);

    }

    void odd(std::function<void(int)> printNumber) {
        if (i > n) {
            return;
        }
        cout<<"printing odd sem ";
        printSem(sOdd);
        cout<<endl;

        sem_wait(&sOdd);
        i++;
        printNumber(i-1);
        sem_post(&sZero);

    }
};
void printNumber(int x){
    cout<<x<<endl;
}

int main(){
    // auto x = new ZeroEvenOdd(3);
    // thread t1(x->zero, printNumber);
    // thread t2(x->even, printNumber);
    // thread t3(x->odd, printNumber);
    ZeroEvenOdd zeroEvenOdd(3);
    thread t1(&ZeroEvenOdd::zero, &zeroEvenOdd, printNumber);
    thread t2(&ZeroEvenOdd::even, &zeroEvenOdd, printNumber);
    thread t3(&ZeroEvenOdd::odd, &zeroEvenOdd, printNumber);
    t1.join();
    t2.join();
    t3.join();
}
Posted
Updated 18-Jul-23 20:25pm

1 solution

In your case, the debug is simple, just by inspection: the zero method (t1) unlocks sOdd and then exits. Then the odd method (t3) terminates (because sOdd is unlocked). The even method has no chance to exit, because sEven is still locked.
You can observe such a behavior adding messages at the end of the methods:
void zero(std::function<void(int)> printNumber) {
    //...
      cout << "zero terminating\n";
  }

and so on.
 
Share this answer
 

This content, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)



CodeProject, 20 Bay Street, 11th Floor Toronto, Ontario, Canada M5J 2N8 +1 (416) 849-8900