线程所有者的互斥锁

时间:2018-02-05 17:17:09

标签: c++ pthreads c++14

根据几个文档示例,线程无法解锁互斥锁,除非它明确地锁定它。以下是IBM的pthread_mutex_unlock手册页的摘录。

  

pthread_mutex_unlock()函数解锁指定的互斥锁。如果   调用线程当前不持有互斥锁(通过前一个   调用pthread_mutex_lock(),pthread_mutex_trylock()或   pthread_mutex_timedlock_np())解锁请求因EPERM失败   错误。

即使是新的C ++标准也提到了类似于线程所有权的东西,但是下面的程序能够解锁锁定在不同线程上的互斥锁。在gcc& Linux系统在pthread互斥体和std :: mutex上都看到了相同的行为(我认为无论如何都是基于pthread_mutex实现的)。

=Table.TransformColumns(Test, {"Count", each Table.AddColumn(_, "Target", (inner) => inner[Monthly Target]/Table.RowCount(_))})

我对互操作“所有权”的理解中遗漏了什么?

1 个答案:

答案 0 :(得分:0)

请求失败,EPERM错误仅针对使用PTHREAD_MUTEX_ERRORCHECK创建的互斥锁。

请参阅pthread_mutex_lock部分RATIONALE:

  

...虽然能够提取互斥锁所有者的线程ID可能是合乎需要的,但是当每个互斥锁被锁定时,它需要存储当前线程ID,这可能会产生不可接受的开销水平。

即。使用PTHREAD_ERRORCHECK_MUTEX_INITIALIZER_NP初始化您的互斥锁。

示例:

void locker(pthread_mutex_t* mutex) {
    if(int e = pthread_mutex_lock(mutex))
        fprintf(stderr, "pthread_mutex_lock: (%d)%s\n", e, strerror(e));
}

void unlocker(pthread_mutex_t* mutex) {
    if(int e = pthread_mutex_unlock(mutex))
        fprintf(stderr, "pthread_mutex_unlock: (%d)%s\n", e, strerror(e));
}

int main() {
    pthread_mutex_t a = PTHREAD_MUTEX_INITIALIZER;
    pthread_mutex_t b = PTHREAD_ERRORCHECK_MUTEX_INITIALIZER_NP;
    std::thread(locker, &a).join();
    std::thread(locker, &b).join();
    std::thread(unlocker, &a).join();
    std::thread(unlocker, &b).join(); // pthread_mutex_unlock: (1)Operation not permitted
}