I am not able to print the output on the screen. I am using cppreference side (GCC 12.1 (c++20 )) compiler

96 Views Asked by At

I am not able to print the output on the screen.I am using cppreference side (GCC 12.1 (c++20 )) compiler, Is there any deadlock situation in below example. Is there any online compiler i can use for trying this type of examples

#include <iostream>
#include <semaphore>
#include <thread>
#include <vector>

std::vector<int> myVec{};
std::counting_semaphore<1> prepareSignal(2);              // (1)

void prepareWork() 
{

    myVec.insert(myVec.end(), {0, 1, 0, 3});
    std::cout << "Sender: Data prepared."  << '\n';
    prepareSignal.release();                              // (2)
}

void completeWork() 
{

    std::cout << "Waiter: Waiting for data." << '\n';
    prepareSignal.acquire();                              // (3)
    myVec[2] = 2;
    std::cout << "Waiter: Complete the work." << '\n';
    for (auto i: myVec) std::cout << i << " ";
    std::cout << '\n';
}

int main() 
{
    std::cout << '\n';
    std::thread t1(prepareWork);
    std::thread t3(completeWork);
    std::thread t2(completeWork);
    t1.join();
    t3.join();
    t2.join();
    std::cout << '\n';
}
1

There are 1 best solutions below

1
On BEST ANSWER

There is no deadlock, but you have a race condition:

In completeWork, prepareSignal.acquire does not block the execution (Based on c++ documentation: "When the counter is zero, acquire() blocks until the counter is incremented"). In this case, the counter is set to 2, and there is no other acquire.

So the program may run completeWork earlier than prepareWork, which will execute myVec[2] = 2;. This causes undefined behavior since your vector is empty.

You can test such errors using Address Sanitizer.

See a live example here that highlights this issue by adding a 1 second sleep delay to prepareWork:

https://godbolt.org/z/YYsfq84bd

The address sanitizer output tells you exactly where the error is!