Программа на C ++, использующая мьютекс, дает непредсказуемый результат.Ожидание тупика, но не получить его - PullRequest
0 голосов
/ 26 октября 2018

У меня есть код, использующий мьютекс для самообучения.Ссылка: https://baptiste -wicht.com / posts / 2012/04 / c11-concurrency-tutorial-advanced-lock-and-condition-variables.html

Я написал пример: 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;
}

Я ожидаю, что этот код будет иметь тупиковую ситуацию при вызове mul () из обоих (), так как оба () уже получают мьютекс, поэтому mul () должен быть заблокирован.

Теперь я использую: Ubuntu 17.10.1 с g ++ (Ubuntu 7.2.0-8ubuntu3.2) 7.2.0 (вывод g ++ --version)

Если я использую команду компиляции:

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

У меня вообще нет тупика!

Но если я использую команду компиляции:

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

Все работает - значит, я вижу тупик.

Можете объяснить?Кроме того, как первая команда делает код скомпилированным?Я не упомянул pthreads и не упомянул -std = c ++ 11, хотя код использует c ++ 11 lib?Я ожидал бы неудачу компиляции / связывания?

Спасибо.

1 Ответ

0 голосов
/ 26 октября 2018

Ответ таков: если вы не компилируете и не связываете с -pthread, тогда вы не используете фактические функции блокировки pthread.

Библиотека GNU Linux C настроена таким образом, что библиотеки могут вызывать всеиз функций блокировки, но если они на самом деле не связаны в многопоточную программу, ни одна из блокировок фактически не происходит.

...