有没有人知道如何在不使用wait()
,notify()
或synchronize
的情况下在java中实现基本信号量。我不是只想找到解决这个问题的方法指针朝着正确的方向,因为我完全迷失了。
答案 0 :(得分:2)
答案 1 :(得分:1)
这是我在C ++中实现signal和wait的实现,但我不知道它是否会有所帮助,因为你必须实现很多其他的东西。
int KernelSem::wait() {
lock();
if(--value < 0) {
PCB::running->state = PCB::BLOCKED;
PCB::running->waitingAtSem = this;
blockedQueue->put(PCB::running);
dispatch();
}
else {
PCB::running->deblockedBy = 0;
if(semPreempt) dispatch();
}
unlock();
return PCB::running->deblockedBy;
}
void KernelSem::signal() {
lock();
if(value++ < 0) {
PCB* tempPCB = blockedQueue->get();
if(tempPCB) {
tempPCB->state = PCB::READY;
tempPCB->deblockedBy = 0;
tempPCB->waitingAtSem = 0;
Scheduler::put(tempPCB);
}
}
if(semPreempt) dispatch();
unlock();
}
锁定和解锁功能只是asm{cli}
和asm{sti}
(清除/设置中断标志)。
PCB是process control block。
希望有所帮助
答案 2 :(得分:0)
我希望这是作业,因为我看不出你有什么理由想在生产代码中这样做。维基百科有一个algorithms for implementing semaphores in software的列表。
答案 3 :(得分:0)
以一种非常简单(简单)的简单方式,您可以使用简单的int或boolean实现它。
在授予访问权限之前测试int或boolean。如果它为0(厌倦了布尔值),则加1并继续。如果没有做Thread.yield()并再次尝试。释放时,从int中删除1并继续。
天真的实施,但工作正常。
答案 4 :(得分:0)
按照接受的答案中的建议进行操作会导致很多并发问题,因为您无法确保互相排斥。作为一个例子,两个要求递增整数的线程同时读取布尔值(建议作为锁定),然后两者都认为它没问题,然后两者都将bool设置为相反的值。两个线程都会进行更改,当它们完成时,它们都会向(非)互斥变量写入一个值,并且信号量的整个目的都会丢失。 wait()方法用于等待事情发生,这正是您想要做的事情。
如果你绝对不想使用wait,那么实现某种双重检查睡眠技术,其中线程首先检查锁变量,将其更改为false并在数组中设置标志或具有特殊功能的东西只为该线程插槽以确保它始终成功。然后线程可以休眠一小段时间,然后检查整个数组以获得更多标志,以查看其他人是否在同一时间。如果没有,它可以继续,否则它不能继续并且必须在再次尝试之前休眠一段时间(以使线程长时间睡眠以使某人稍后成功)。如果它们再次坍塌,那么它们将会睡眠更长的随机时间。该技术也用于不能使用信号量的网络中。
(当然信号量正是你想要做的,但是因为它使用了等待我认为你想要的东西根本不用等待......)