Multithreading 无法正确实现互斥
我正在尝试实现一个互斥而不必等待。基本上,如果一个线程想要锁,它会检查互斥锁是否已经被锁定,如果已经被锁定,则将该线程置于睡眠状态,并将其添加到FIFO队列中。当持有锁的线程去解锁互斥锁时,它会检查是否有线程正在等待访问关键区域,如果是,则从队列中删除该线程,并将其添加到“就绪”队列中,该队列控制正在使用的线程的顺序 我无法让互斥锁工作,但它下面的信号灯工作正常。有什么想法吗?谢谢Multithreading 无法正确实现互斥,multithreading,concurrency,mutex,semaphore,Multithreading,Concurrency,Mutex,Semaphore,我正在尝试实现一个互斥而不必等待。基本上,如果一个线程想要锁,它会检查互斥锁是否已经被锁定,如果已经被锁定,则将该线程置于睡眠状态,并将其添加到FIFO队列中。当持有锁的线程去解锁互斥锁时,它会检查是否有线程正在等待访问关键区域,如果是,则从队列中删除该线程,并将其添加到“就绪”队列中,该队列控制正在使用的线程的顺序 我无法让互斥锁工作,但它下面的信号灯工作正常。有什么想法吗?谢谢 // DOESN'T WORK class Mutex { Thread * thisThread;
// DOESN'T WORK
class Mutex {
Thread * thisThread;
Thread * threadWithLock;
lock() {
// disable interrupts
interrupts.disable();
// if no-one has lock, give lock to the current thread and set the lock
// else put the thread to sleep and add it to the waiting thread queue
if (lockStatus == 0) {
lock = 1
threadWithLock = thisThread;
} else {
sleepingThreads.enqueue(thisThread);
thisThread.sleep();
}
// re-enable previous interrupt status
interrupts.revert();
}
unlock() {
// disable interrupts
interrupts.disable();
// if there is a thread waiting for the lock, add it to the ready list
if (sleepingThreads.isEmpty() == false) {
Thread * t = sleepingThreads.dequeue();
t.updateStatus(READY);
threadReadyList.enqueue(t);
}
// release lock
threadWithLock = null;
lock = 0;
// re-enable previous interrupt status
interrupts.revert();
}
}
// WORKS
class Semaphore {
Thread * thisThread;
down() {
// disable interrupts
interrupts.disable();
readyCount -= 1;
if (readyCount < 0) {
sleepingThreads.enqueue(thisThread);
thisThread.sleep();
}
// re-enable previous interrupt status
interrupts.revert();
}
up () {
// disable interrupts
interrupts.disable();
readyCount += + 1;
if (readyCount <= 0) {
Thread * t = null;
t = sleepingThreads.dequeue();
t.updateStatus(READY);
threadReadyList.enqueue(t);
}
// re-enable previous interrupt status
interrupts.revert();
}
}
问题是我没有将锁交给队列中等待的下一个线程。这与中断状态无关。正确的解锁()如下所示
unlock() {
// disable interrupts
interrupts.disable();
// if there is a thread waiting for the lock, add it to the ready list,
// and hand the lock over
if (sleepingThreads.isEmpty() == false) {
Thread * t = sleepingThreads.dequeue();
t.updateStatus(READY);
threadReadyList.enqueue(t);
threadWithLock = t;
} else {
//release the lock
threadWithLock = null;
lock = 0
}
// re-enable previous interrupt status
interrupts.revert();
}
unlock() {
// disable interrupts
interrupts.disable();
// if there is a thread waiting for the lock, add it to the ready list,
// and hand the lock over
if (sleepingThreads.isEmpty() == false) {
Thread * t = sleepingThreads.dequeue();
t.updateStatus(READY);
threadReadyList.enqueue(t);
threadWithLock = t;
} else {
//release the lock
threadWithLock = null;
lock = 0
}
// re-enable previous interrupt status
interrupts.revert();
}
我想你将来可能会遇到中断被禁用的问题。在将等待线程添加到队列后,您可能希望恢复中断。我认为,互斥实现是不正确的。锁定互斥锁的线程必须解锁互斥锁,而信号量的情况并非如此。@Greyson。。或者,换句话说,禁用中断对于任何抢占式多任务处理程序来说都是一场灾难。sleep()仅在间隔很短,以致编译器在高频计时器(或等效计时器)上插入轮询循环,而不是将线程状态更改为[任何未运行的状态]的情况下才能工作。