在rt-thread源码中的rt_mutex_take()里有这样一段代码
if (mutex->owner == thread) { /* it's the same thread */ mutex->hold ++; }
之前不理解在什么情况下线程会重复进入其所持有锁的保护区域,后来看到Vxworks Programmers Guide5.5里的一段解释和对应的例子
/* Function A requires access to a resource which it acquires by taking * mySem; * Function A may also need to call function B, which also requires mySem: */ /* includes */ #include "vxWorks.h" #include "semLib.h" SEM_ID mySem; /* Create a mutual-exclusion semaphore. */ init () { mySem = semMCreate (SEM_Q_PRIORITY); } funcA () { semTake (mySem, WAIT_FOREVER); printf ("funcA: Got mutual-exclusion semaphore\n"); ... funcB (); ... semGive (mySem); printf ("funcA: Released mutual-exclusion semaphore\n"); } funcB () { semTake (mySem, WAIT_FOREVER); printf ("funcB: Got mutual-exclusion semaphore\n"); ... semGive (mySem); printf ("funcB: Releases mutual-exclusion semaphore\n"); }
假设thread1调用funcA(),funcA再调用funcB(),这是没有问题的
假设thread2直接调用funB(),funB()里的这段临界区也是可以被保护的
这都得益于mutex的owner机制,如果是二值信号量这样操作的话,funcB()试图获得mySem的时候就会挂起,不能返回funcA(),mySem就一直得不到释放,形成死锁,也就是rt-thread manual里提到的
owner机制还有一个作用,就是通过优先级继承实现优先级翻转,参考stackoverflow上的一个解答
Another property that comes with a sense of ownership in a mutex is the ability to support priority inheritance. Because the kernel can track the thread owning the mutex and also the identity of all the blocker(s), in a priority threaded system it becomes possible to escalate the priority of the thread that currently owns the mutex to the priority of the highest priority thread that is currently blocking on the mutex. This inheritance prevents the problem of priority inversion that can occur in such cases. (Note that not all systems support priority inheritance on such mutexes, but it is another feature that becomes possible via the notion of ownership).
If you refer to classic VxWorks RTOS kernel, they define three mechanisms:
mutex - supports recursion, and optionally priority inheritance
binary semaphore - no recursion, no inheritance, simple exclusion, taker and giver does not have to be same thread, broadcast release available
counting semaphore - no recursion or inheritance, acts as a coherent resource counter from any desired initial count, threads only block where net count against the resource is zero.
在使用rt_mutex_release()释放锁的时候,除了将mutex的value加1(mutex->value++),还需要将mutex的owner指向NULL(mutex->owner = RT_NULL),否则如果该mutex的owner还是这个线程,当下次这个锁未被占有,而这个线程又试图通过rt_mutex_take()获得锁的时候,就只有hold++,而没有value--,起不到临界区保护的作用
补充:Linux系统里是不支持recursive lock的(参考《Linux Kernel Development》第三版),内核里对应上锁的API是mutex_lock()
但是,在应用层编程上, pthread_mutexattr_settype()里可以设置flag为PTHREAD_MUTEX_RECURSIVE,对应上锁的API是pthread_mutex_lock()
相关推荐
#0 0x00002b9405ea1c38 in __lll_mutex_lock_wait () from /lib64/libc.so.6 #1 0x00002b9405e45e5f in _L_lock_4026 () from /lib64/libc.so.6 #2 0x00002b9405e42df1 in free () from /lib64/libc.so.6 #3 0x00002...
ucos-ii中互斥信号mutex建立源码
32位android中bionic是32位的,其中的mutex只有一半也就是16位能够存储pid,当通过docker运行android时,大概率pid会超过16位的范围,就可能会导致android中mutex死锁,表现为应用卡住黑屏。 [32-bit ABI bugs]...
Latch_Lock_And_Mutex_Contention_Troubleshooting
多线程之间的同步与互斥,详情看博客:http://blog.csdn.net/mybelief321/article/details/9390707
利用mutex object编写的多线程运用程序, 可以直接运行,可以手动改变线程优先级, 很直观。
MPI_Mutex MPI的互斥体仿真 用法 该互斥锁旨在锁定特定的远程内存(RM... MPI_Comm_dup (MPI_COMM_WORLD, &mutex_Comm); if (world_rank == 0 ) { // mpi mutex ************************************************
linux 同步与互斥 posix 线程互斥 实现 。(此为博客http://blog.csdn.net/shallnet 文章对应源码下载)
对于动态分配的互斥量, 在申请内存(malloc)之后, 通过pthread_mutex_init进行初始化, 并且在释放内存(free)前需要调用pthread_mutex_destroy. 原型: int pthread_mutex_init(pthread_mutex_t *restrict mutex, ...
Something useful for multithread mutex.
主线程里使用快速排序QuickSort,其他四个算法分别建立四个子线程,在子线程中进行排序。因为每一个线程都要调用函数PrintResult把结果输出到显示器上,所以不同的线程就会争夺着向显示器输出,这样,不同线程的输出...
它比boost::shared_mutex快。 lock_shared非常贪婪,因此等待lock时间是不公平的。 这应该没有问题,因为此互斥对象适用于被动写入器-主动读取器方案。 最好情况下, lock_shared只是一个fetch_add 。 在最佳...
Implementation of the mutex library over the Linux API.
a tutorial on how to implement and optimize mutexes with gcc inline assembly
linux 同步与互斥 system V 信号量 实现 。(此为博客http://blog.csdn.net/shallnet 文章对应源码下载)
linux 同步与互斥 posix 线程同步互斥 消费者生产者 实现 。(此为博客http://blog.csdn.net/shallnet 文章对应源码下载)
ucosii在stm32单片机上的实验代码,开发环境为keil4
多线程编程:互斥锁使用。 打包文件包含两个文件:c文件源代码、Makefile文件,运行环境在Ubuntu14.04下,使用自带的gcc编译器,同学们只需将文件夹复制到某一目录下之后在终端执行:1.“make”生成“test”可执行...
通过stm32实现的,在UCOS系统上面做的,完成了界面、触摸屏、录音、舵机等,整合到一起 添加了图片,按钮,表格之类的控件,多任务实现