Rag*_*thy 6 multithreading operating-system locks
我正在阅读 Remzi 教授的 OSTEP 书 http://pages.cs.wisc.edu/~remzi/OSTEP/
我只能部分理解以下代码如何导致唤醒/等待竞争条件。(代码取自书籍章节。http: //pages.cs.wisc.edu/~remzi/OSTEP/threads-locks.pdf
void lock(lock_t *m) {
while (TestAndSet(&m->guard, 1) == 1); //acquire guard lock by spinning
if (m->flag == 0) {
m->flag = 1; // lock is acquired
m->guard = 0;
} else {
queue_add(m->q, gettid());
m->guard = 0;
park();
}
}
}
void unlock(lock_t *m) {
while (TestAndSet(&m->guard, 1) == 1); //acquire guard lock by spinning
if (queue_empty(m->q))
m->flag = 0; // let go of lock; no one wants it
else
unpark(queue_remove(m->q)); // hold lock (for next thread!)
m->guard = 0;
}
Run Code Online (Sandbox Code Playgroud)
Park() 系统调用将调用线程置于睡眠状态,而 unpark(threadID) 用于唤醒由 threadID 指定的特定线程。
现在如果线程1通过将m->flag设置为1来持有锁。如果线程2进来获取锁,则失败。因此,执行 else 情况,并将 thread2 添加到队列中,但假设-if在进行 park() 系统调用之前,thread2 被调度出去,并且 thread1 被给予时间片。如果线程1释放锁,unlock函数会尝试调用unpark系统调用(队列非空),因为线程2在队列中。但是thread2没有调用park()系统调用,它只是被添加到队列中。
所以问题是
1) thread1 的 unpark() 返回什么,只是一个错误说找不到 threadID?(特定于操作系统)
2)锁标志会发生什么?它应该在调用锁例程的后续线程之间传递,仅当不再有锁争用时才释放锁。
书上说 thread2 将永远休眠。但我的理解是任何争夺锁的后续线程都将永远休眠,比如线程3稍后尝试获取锁,因为在解锁调用期间锁永远不会被线程1释放。
我的理解很可能是错误的,因为这本书非常具体地指出 thread2 永远休眠。或者我只是在例子中读了太多而我的理解是正确的?!!!并且出现僵局?
将此问题邮寄给Remzi教授并得到了他的答复!只是在这里发布回复。
Remzi教授的回复:
好问题!
我认为你基本上是对的。
unpark() 将返回(也许会说 threadID 没有休眠);在此实现中,锁保持锁定状态,并且 thread2 将永远休眠,正如您所说,所有尝试获取锁的后续线程将无法这样做。
| 归档时间: |
|
| 查看次数: |
1162 次 |
| 最近记录: |