【问题标题】:Locking mutex in one thread and unlocking it in the other在一个线程中锁定互斥锁并在另一个线程中解锁它
【发布时间】:2023-03-24 08:25:02
【问题描述】:

此代码是否正确且可移植?

void* aThread(void*)
{
    while(conditionA)
    {
        pthread_mutex_lock(mutex1);
        //do something
        pthread_mutex_unlock(mutex2);
    }
}

void* bThread(void*)
{
    while(conditionB)
    {
        pthread_mutex_lock(mutex2);
        //do something
        pthread_mutex_unlock(mutex1);
    }
}

在实际应用程序中,我有三个线程 - 两个用于向数组添加值,一个用于读取它们。而且我需要第三个线程在其他线程之一添加新项目之后立即显示数组的内容。

【问题讨论】:

    标签: pthreads mutex


    【解决方案1】:

    事实并非如此。如果线程 A 在线程 B 到达 mutex_lock(2) 之前到达 mutex_unlock(2),则您将面临未定义的行为。你也不能解锁另一个线程的互斥锁。

    pthread_mutex_lock Open Group Base Specification 是这么说的:

    如果互斥锁类型是 PTHREAD_MUTEX_NORMAL [...] 如果线程尝试解锁它尚未锁定的互斥锁或解锁的互斥锁,则会导致未定义的行为。

    【讨论】:

    • 好的。但是如何解锁已锁定在另一个线程中的互斥锁呢?还有未定义的行为?
    • 就像它说的:“如果一个线程试图解锁一个它没有锁定的互斥锁...... UB”
    【解决方案2】:

    作为user562734's answer says,答案是否定的——您无法解锁被另一个线程锁定的线程。

    要实现你想要的读写器同步,你应该使用条件变量——pthread_cond_wait()pthread_cond_signal()和相关函数。

    【讨论】:

    • 信号量有时也适用于您希望能够“解锁另一个线程的锁”的情况。它们实际上是一个很好的解决方法,因为记录在案的推荐使用 pthread_atfork 会调用未定义的行为。 :-)
    【解决方案3】:

    某些实现确实允许锁定和解锁线程 与众不同。

    #include <iostream>
    #include <thread> 
    #include <mutex> 
    
    using namespace std;
    
    mutex m;
    
    void f() {m.lock();   cout << "f: mutex is locked" << endl;}
    
    void g() {m.unlock(); cout << "g: mutex is unlocked" << endl;}
    
    main()
    {
          thread tf(f);    /* start f                           */
          tf.join();       /* Wait for f to terminate           */
          thread tg(g);    /* start g                           */
          tg.join();       /* Wait for g to terminate           */
    }
    

    这个程序打印

    f: 互斥锁被锁定 g: 互斥锁已解锁

    系统是 Debian linux,gcc 4.9.1。 -std=c++11.

    【讨论】:

    • gcc 4.9.1 的实现是否明确说明了这一点?如果不是,并且您只是从实验中得到了答案,那么它仍然是 UB,即使在这种情况下它似乎正在工作。
    猜你喜欢
    • 1970-01-01
    • 2023-03-21
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-12-25
    相关资源
    最近更新 更多