Multithreading 无法正确实现互斥

Multithreading 无法正确实现互斥,multithreading,concurrency,mutex,semaphore,Multithreading,Concurrency,Mutex,Semaphore,我正在尝试实现一个互斥而不必等待。基本上,如果一个线程想要锁,它会检查互斥锁是否已经被锁定,如果已经被锁定,则将该线程置于睡眠状态,并将其添加到FIFO队列中。当持有锁的线程去解锁互斥锁时,它会检查是否有线程正在等待访问关键区域,如果是,则从队列中删除该线程,并将其添加到“就绪”队列中,该队列控制正在使用的线程的顺序 我无法让互斥锁工作,但它下面的信号灯工作正常。有什么想法吗?谢谢 // DOESN'T WORK class Mutex { Thread * thisThread;

我正在尝试实现一个互斥而不必等待。基本上,如果一个线程想要锁,它会检查互斥锁是否已经被锁定,如果已经被锁定,则将该线程置于睡眠状态,并将其添加到FIFO队列中。当持有锁的线程去解锁互斥锁时,它会检查是否有线程正在等待访问关键区域,如果是,则从队列中删除该线程,并将其添加到“就绪”队列中,该队列控制正在使用的线程的顺序

我无法让互斥锁工作,但它下面的信号灯工作正常。有什么想法吗?谢谢

// 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()仅在间隔很短,以致编译器在高频计时器(或等效计时器)上插入轮询循环,而不是将线程状态更改为[任何未运行的状态]的情况下才能工作。