使用计数信号量如何创建递归互斥量
Using a counting semaphore how do I create a recursive mutex
我在裸机环境中操作,所以任何回答说只使用你拥有的东西都不适用,因为我什么都没有。我正在编写一个系统驱动程序,但我需要递归互斥锁,但我不知道如何实现它们。我目前只有一个作为自旋锁运行的计数信号量。是否可以从信号量创建递归互斥锁,或者我是否必须创建另一个同步原语,如果可以,如何创建?不需要代码我只是想知道步骤。
如果你对数据竞争下发生的事情有一些相当薄弱的好属性,它很简单,本质上:
/* data structure */
struct my_mutex {
sem_t sem;
volatile tid_t owner;
unsigned count;
} m;
/* lock operation */
if (m->owner == self) { // formally a race
m->cnt++;
} else {
sem_wait(&m->sem);
m->owner = self; // where self is tid of calling thread
}
/* unlock operation */
if (m->count > 0) {
m->count--;
} else {
m->owner = 0;
sem_post(&m->sem);
}
请注意,假设赛车阅读从某些可能的排序中读取了一些价值,没有任何顺序可以让您在自己是所有者时不将自己视为所有者,或者在您不是所有者时也不会将自己视为所有者。但是,如果您将它们视为正式未定义,则无效。
如果你不能这样做,你通常需要一个普通的互斥锁 + condvar 来模拟递归互斥锁,所以首先要弄清楚如何从信号量中创建一个 condvar。
如果你的编译器有 _Atomic
并且支持线程 ID 大小合适的原子(上面的抽象 tid_t
类型;在裸机上这是你定义的类型),你可以tid_t owner
成员 _Atomic
并替换测试:
if (m->owner == self)
与:
if (atomic_load_explicit(&m->owner, memory_order_relaxed) == self)
和 volatile
限定符(在很大程度上是不必要的,但它向编译器发出信号,表明它不应拆分或合并负载,这有助于 "weak nice properties" 我在缺席时的目标原子数)可以删除。
我在裸机环境中操作,所以任何回答说只使用你拥有的东西都不适用,因为我什么都没有。我正在编写一个系统驱动程序,但我需要递归互斥锁,但我不知道如何实现它们。我目前只有一个作为自旋锁运行的计数信号量。是否可以从信号量创建递归互斥锁,或者我是否必须创建另一个同步原语,如果可以,如何创建?不需要代码我只是想知道步骤。
如果你对数据竞争下发生的事情有一些相当薄弱的好属性,它很简单,本质上:
/* data structure */
struct my_mutex {
sem_t sem;
volatile tid_t owner;
unsigned count;
} m;
/* lock operation */
if (m->owner == self) { // formally a race
m->cnt++;
} else {
sem_wait(&m->sem);
m->owner = self; // where self is tid of calling thread
}
/* unlock operation */
if (m->count > 0) {
m->count--;
} else {
m->owner = 0;
sem_post(&m->sem);
}
请注意,假设赛车阅读从某些可能的排序中读取了一些价值,没有任何顺序可以让您在自己是所有者时不将自己视为所有者,或者在您不是所有者时也不会将自己视为所有者。但是,如果您将它们视为正式未定义,则无效。
如果你不能这样做,你通常需要一个普通的互斥锁 + condvar 来模拟递归互斥锁,所以首先要弄清楚如何从信号量中创建一个 condvar。
如果你的编译器有 _Atomic
并且支持线程 ID 大小合适的原子(上面的抽象 tid_t
类型;在裸机上这是你定义的类型),你可以tid_t owner
成员 _Atomic
并替换测试:
if (m->owner == self)
与:
if (atomic_load_explicit(&m->owner, memory_order_relaxed) == self)
和 volatile
限定符(在很大程度上是不必要的,但它向编译器发出信号,表明它不应拆分或合并负载,这有助于 "weak nice properties" 我在缺席时的目标原子数)可以删除。