0

I have code using mutex for self learning. Link is : https://baptiste-wicht.com/posts/2012/04/c11-concurrency-tutorial-advanced-locking-and-condition-variables.html

I wrote the example: main_deadlock.cpp

#include <iostream>
#include <thread>
#include <mutex>

struct Complex {
    std::mutex mutex;
    int i;

    Complex() : i(0) {}

    void mul(int x){
        std::cout << "mul : before lock_guard" << std::endl;
        std::lock_guard<std::mutex> lock(mutex);
        std::cout << "mul : after lock_guard, before operation" << std::endl;
        i *= x;
        std::cout << "mul : after operation" << std::endl;
    }

    void div(int x){
        std::cout << "div : before lock_guard" << std::endl;
        std::lock_guard<std::mutex> lock(mutex);
        std::cout << "div : after lock_guard, before operation" << std::endl;
        i /= x;
        std::cout << "div : after operation" << std::endl;
    }

    void both(int x, int y)
    {
        std::cout << "both : before lock_guard" << std::endl;
        std::lock_guard<std::mutex> lock(mutex);
        std::cout << "both : after lock_guard, before mul()" << std::endl;
        mul(x);
        std::cout << "both : after mul(), before div()" << std::endl;
        div(y);
        std::cout << "both : after div()" << std::endl;
    }

};

int main(){

    std::cout << "main : starting" << std::endl;
    Complex complex;
    std::cout << "main : calling both()" << std::endl;
    complex.both(32, 23);

    return 0;
}

I would expect this code will have a deadlock when calling mul() from both() cause both() already acquire the mutex, so mul() should be blocked.

Now I am using: ubuntu 17.10.1 with g++ (Ubuntu 7.2.0-8ubuntu3.2) 7.2.0 (g++ --version output)

If I am using the compile command:

user@user: g++ -o out_deadlock main_deadlock.cpp

I get no deadlock at all!

But if I use the compile command:

user@user: g++ -std=c++11 -pthread -o out_deadlock main_deadlock.cpp

All works - means I see deadlock.

Can you explain? also, How the first command makes the code compile? I didn't "mention" pthreads and didn't mention -std=c++11 although code is using c++ 11 lib? I would expect fail of compilation/linkage?

Thanks.

progtec
  • 61
  • 1
  • 4
  • 1
    [std::mutex::lock](https://en.cppreference.com/w/cpp/thread/mutex/lock) : If lock is called by a thread that already owns the mutex, the **behavior is undefined**: for example, the program may deadlock. – Thomas Oct 25 '18 at 23:14
  • Probably without -pthread a dummy interface is used so your code still compiles, but no actual mutex is locked and unlocked.. just a guess. – rmawatson Oct 26 '18 at 00:23
  • https://stackoverflow.com/a/6266345/13422 – Zan Lynx Oct 26 '18 at 07:01

1 Answers1

0

The answer is that if you do not compile and link with -pthread then you are not using actual pthread locking functions.

The GNU Linux C library is set up that way so that libraries can call all of the locking functions, but unless they are actually linked into a multithreaded program, none of the locks actually happen.

Zan Lynx
  • 53,022
  • 10
  • 79
  • 131