首页 > 解决方案 > 使用互斥锁的 C++ 程序会给出不可预测的输出。期待一个僵局,但没有得到它

问题描述

我有使用互斥锁进行自学的代码。链接是:https ://baptiste-wicht.com/posts/2012/04/c11-concurrency-tutorial-advanced-locking-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;
}

我希望这段代码在从 both() 调用 mul() 时会出现死锁,因为 both() 已经获取了互斥锁,所以 mul() 应该被阻止。

现在我正在使用: ubuntu 17.10.1 和 g++ (Ubuntu 7.2.0-8ubuntu3.2) 7.2.0 (g++ --version 输出)

如果我使用编译命令:

用户@用户:g++ -o out_deadlock main_deadlock.cpp

我根本没有僵局!

但是如果我使用编译命令:

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

一切正常 - 意味着我看到了死锁。

你可以解释吗?另外,第一个命令如何使代码编译?我没有“提到” pthreads,也没有提到 -std=c++11 尽管代码使用的是 c++ 11 lib?我希望编译/链接失败?

谢谢。

标签: c++11pthreadsdeadlock

解决方案


答案是,如果你不编译和链接,-pthread那么你就没有使用实际的 pthread 锁定函数。

GNU Linux C 库就是这样设置的,这样库就可以调用所有的锁定函数,但是除非它们实际链接到多线程程序中,否则实际上不会发生任何锁定。


推荐阅读