lock了mutex的线程退出了却没有unlock时会怎么样?

https://stackoverflow.com/questions/4424193/what-happens-to-mutex-when-the-thread-which-acquired-it-exits?noredirect=1&lq=1

解释当一个lock了mutex的线程退出了,却没有主动unlock这个mutex时,会发生什么

If you created a robust mutex by setting up the right attributes before calling pthread_mutex_init, the mutex will enter a special state when the thread that holds the lock terminates, and the next thread to attempt to acquire the mutex will obtain an error of EOWNERDEAD. It is then responsible for cleaning up whatever state the mutex protects and calling pthread_mutex_consistent to make the mutex usable again, or calling pthread_mutex_unlock (which will make the mutex permanently unusable; further attempts to use it will return ENOTRECOVERABLE).

假设在pthread_mutex_init的时候,通过设置合适的属性得到一个robust mutex,当一个拥有该mutex的线程exit,并且没有unlock这个mutex的时候,该mutex就会进入一个specail state。另外一个线程想要lock这个mutex的时候,会返回一个EOWNERDEAD错误。这个时候就需要清除该mutex的状态,有两个办法:

  1. 调用pthread_mutex_consistent可以使得改mutex再次usable
  2. pthread_mutex_unlock使得该mutex永久unusable,尝试再次使用该mutex的将会得到ENOTRECOVERABLE错误

For non-robust mutexes, the mutex is permanently unusable if the thread that locked it terminates without unlocking it. Per the standard (see the resolution to issue 755 on the Austin Group tracker), the mutex remains locked and its formal ownership continues to belong to the thread that exited, and any thread that attempts to lock it will deadlock. If another thread attempts to unlock it, that‘s normally undefined behavior, unless the mutex was created with the PTHREAD_MUTEX_ERRORCHECK attribute, in which case an error will be returned.

对non-robust mutexes,如果持有锁的线程退出且没有unlock该锁,那么该mutex将会永久不可以使用。这个mutex会保持被已经退出的该线程持有lock的状态,任何尝试lock这个mutex的线程将陷入deadlock状态。如果任何线程尝试unlock这个mutex,那么将会产生undefined behavior。但如果mutex创建的时候设置了PTHREAD_MUTEX_ERRORCHECK属性,那么unlock将会返回错误。

On the other hand, many (most?) real-world implementations don‘t actually follow the requirements of the standard. An attempt to lock or unlock the mutex from another thread might spuriously succeed, since the thread id (used to track ownership) might have been reused and may now refer to a different thread (possibly the one making the new lock/unlock request). At least glibc‘s NPTL is known to exhibit this behavior.

但是,很多real-world的实现版本却没有满足standard的要求。由于thread id可能会被重用,所以,有时候lock或者unlock会产生不合逻辑的成功,比如一个线程A lock了某个mutex,然后该A线程id给别的线程B用了,那么线程B去unlock也会成功。比如glibc‘s NPTL就会表现出这样的行为。

原文地址:https://www.cnblogs.com/willhua/p/10114001.html

时间: 2024-08-29 01:13:31

lock了mutex的线程退出了却没有unlock时会怎么样?的相关文章

线程系列08,实现线程锁的各种方式,使用lock,Montor,Mutex,Semaphore以及线程死锁

当涉及到多线程共享数据,需要数据同步的时候,就可以考虑使用线程锁了.本篇体验线程锁的各种用法以及线程死锁.主要包括: ※ 使用lock处理数据同步※ 使用Monitor.Enter和Monitor.Exit处理数据同步※ 使用Mutex处理进程间数据同步※ 使用Semaphore处理数据同步※ 线程死锁 □ 使用lock处理数据同步 假设有一个类,主要用来计算该类2个字段的商,在计算商的方法之内让被除数自减,即被除数有可能为零.使用lock语句块保证每次只有一个线程进入该方法. class Th

13 join 线程锁之Lock\Rlock\信号量 将线程变为守护进程 Event事件  queue队列 生产者消费者模型 Queue队列 开发一个线程池

本节内容 操作系统发展史介绍 进程.与线程区别 python GIL全局解释器锁 线程 语法 join 线程锁之Lock\Rlock\信号量 将线程变为守护进程 Event事件 queue队列 生产者消费者模型 Queue队列 开发一个线程池 进程 语法 进程间通讯 进程池 操作系统发展史 手工操作(无操作系统) 1946年第一台计算机诞生--20世纪50年代中期,还未出现操作系统,计算机工作采用手工操作方式. 手工操作程序员将对应于程序和数据的已穿孔的纸带(或卡片)装入输入机,然后启动输入机把

C#使用Monitor类、Lock和Mutex类进行多线程同步

在多线程中,为了使数据保持一致性必须要对数据或是访问数据的函数加锁,在数据库中这是很常见的,但是在程序中由于大部分都是单线程的程序,所以没有加锁的必要,但是在多线程中,为了保持数据的同步,一定要加锁,好在Framework中已经为我们提供了三个加锁的机制,分别是Monitor类.Lock关键字和Mutex类. 其中Lock关键词用法比较简单,Monitor类和Lock的用法差不多.这两个都是锁定数据或是锁定被调用的函数.而Mutex则多用于锁定多线程间的同步调用.简单的说,Monitor和Loc

线程退出前操作

#include <unistd.h> #include <pthread.h> #include <stdio.h> #include <stdlib.h> void cleanup() { printf("cleanup\n"); } void *test_cancel(void) { pthread_cleanup_push(cleanup,NULL); printf("test_cancel\n"); whil

[转载]DllMain中不当操作导致死锁问题的分析--线程退出时产生了死锁

(转载于breaksoftware的csdn博客) 我们回顾下之前举得例子 case DLL_PROCESS_ATTACH: { printf("DLL DllWithoutDisableThreadLibraryCalls_A:\tProcess attach (tid = %d)\n", tid); HANDLE hThread = CreateThread(NULL, 0, ThreadCreateInDllMain, NULL, 0, NULL); WaitForSingleO

015 线程退出 启动

线程退出 启动  ● 当一个进程销毁的时候 ○ 销毁临时对象 ○ 释放堆栈 ○ 将返回值设置为我的退出代码 ○ 减少进程内核对象的使用次数 ● 当一个线程销毁的时候 ○ 销毁临时对象 调用我的们的析构函数 ○ 释放当前线程里面锁分配堆栈 -> 窗口 -> HOOK ○ 将返回值设置为我的退出代码 线程的入口函数的返回值设置为我的退出代码 ○ 减少进程内核对象的使用次数 ● ExitThread 立即结束当前线程 ● TerminateThread 可以结束其他的线程 ● Exit ○ 会将属于

c# 中的 lock monitor mutex Semaphore 的比较

直接贴文章好了,这些大神都讲解的很清楚: c# 中的 mutex https://msdn.microsoft.com/en-us/library/system.threading.mutex(v=vs.110).aspx c# 中的 lock monitor mutex Semaphore  的比较 https://abhijit-k-adhikari.me/2012/04/17/lock-monitor-mutex-semaphore/ https://www.onlinebuff.com/

C#多线程:深入了解线程同步lock,Monitor,Mutex,同步事件和等待句柄(中)

本篇继续介绍WaitHandler类及其子类 Mutex,ManualResetEvent,AutoResetEvent的用法..NET中线程同步的方式多的让人看了眼花缭乱,究竟该怎么去理解呢?其实,我们抛开.NET环境看线程同步,无非是执行两种操作:一是互斥/加锁,目的是保证临界区代码操作的"原子性":另一种是信号灯操作,目的是保证多个线程按照一定顺序执行,如生产者线程要先于消费者线程执行..NET中线程同步的类无非是对这两种方式的封装,目的归根结底都可以归结为实现互斥/ 加锁或者是

【转】多线程:C#线程同步lock,Monitor,Mutex,同步事件和等待句柄(上)

本篇从Monitor,Mutex,ManualResetEvent,AutoResetEvent,WaitHandler的类关系图开始,希望通过 本篇的介绍能对常见的线程同步方法有一个整体的认识,而对每种方式的使用细节,适用场合不会过多解释.让我们来看看这几个类的关系图: 1.lock关键字      lock是C#关键词,它将语句块标记为临界区,确保当一个线程位于代码的临界区时,另一个线程不进入临界区.如果其他线程试图进入锁定的代码,则它将一直等待(即被阻止),直到该对象被释放.方法是获取给定