c++ - pthread_mutex_lock 当它是同一个线程时如何不锁定

标签 c++ c multithreading mutex

我正在使用 pthread_mutex_t 进行锁定。

pthread_mutex_t m_lock;

void get1() {
    cout<<"Start get 1"<<endl;
    pthread_mutex_lock(&m_lock);
    get2();
    pthread_mutex_unlock(&m_lock);
    cout<<"End get 1"<<endl;
}

void get2() {
    cout<<"Start get 2"<<endl;
    pthread_mutex_lock(&m_lock); // The program actually stops here because it waits to m_lock to be unlock from get1 function.
    pthread_mutex_unlock(&m_lock);
    cout<<"End get 2"<<endl;
}

// The thread call to run function
void* run(void* p) {
    get1();
}

假设我只有一个调用 run 函数的线程,所以: get1 锁定 m_lock 并调用 get2,但是当它尝试锁定 m_lock 时,它会等待锁被解锁(这并没有发生),我们遇到了死锁。

我的问题是,当在 get1 中锁定锁的同一个线程不需要等待 get2 中的锁(因为它是同一个线程)时,我该如何避免这种情况?

例如,在 Java 中,当您使用 synchornized 时,这种情况永远不会发生。

public Test implements Runnable {
    public void get1() {
        System.out.println("Start get 1");
        synchronized (this) {
            get2();
        }
        System.out.println("End get 1");
    }

    public void get2() {
        System.out.println("Start get 2");
        synchronized (this) {

        }
        System.out.println("End get 2");
    }

    @Override
    public void run() {
        get1();
    }
}

这里没有死锁。

请在我的 C 代码中得到相同的结果。

谢谢。

最佳答案

正如 Kami Kaze 在评论中指出的那样,如果这是您的完整示例,那么这不是问题:只有一条路径通向 get2,并且这条路径已经获取了互斥体;简单地省略第二次获取它。

但是,一般来说,可能会想到不太清楚的场景。在这种情况下,您可以使互斥体 recursive/reentrant :

In computer science, the reentrant mutex (recursive mutex, recursive lock) is particular type of mutual exclusion (mutex) device that may be locked multiple times by the same process/thread, without causing a deadlock.

在您的设置中,这将通过 pthread_mutexattr_settype 进行:

pthread_mutexattr_settype(&m_lock, PTHREAD_MUTEX_RECURSIVE);

关于c++ - pthread_mutex_lock 当它是同一个线程时如何不锁定,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/39916691/

相关文章:

java - Java 线程安全适用于类的所有实例还是仅适用于共享实例?

c# - 将参数传递给线程

C++,从函数返回字符串; boost::asio 读/写

c++ - 没有图像的词袋

c - 程序通过C预处理器后,这个声明行会变成什么?

c - getaddrinfo - 数字服务与命名服务的结果不同

java - Netty (netty-all-4.1.12.Final.jar) java.io.IOException : An existing connection was forcibly closed by the remote host

c++ - 无法编译以下代码以访问结构的变体

c++ - 原生 C++ 中的函数覆盖

C中的压缩程序