信号量是阻塞调用线程还是线程本身阻塞?

时间:2018-07-11 13:07:54

标签: multithreading

我目前正在学习信号量。 我知道他们在那里可以限制对并发系统中资源的访问。 f.e.在Java中,信号量类具有调用进程将访问的方法aquire()release()

现在,通常,当信号量具有四个打开的空间并且四个线程尝试获取访问权限时,将授予该访问权限。
但是,如果第五个线程试图访问该资源,则该线程必须被阻塞或以某种方式设置为休眠。作为程序员,我是否必须实现

if (semaphore.hasSpaceleft()){  
    semaphore.aquire();  
    ressource.access();  
} else {  
    sleep until semaphore.hasSpaceLeft();  
}

还是该信号量处理休眠/阻塞调用线程? (不仅在Java中,而且在一般情况下)

1 个答案:

答案 0 :(得分:2)

否,according to docs

if (semaphore.hasSpaceleft()){  // 1
    semaphore.aquire();         // 2
    ressource.access();
} else {  
    sleep until semaphore.hasSpaceLeft();  
}
     

从此信号灯获取许可,阻止,直到一个   可用,否则线程被中断。

重点增强


实际上,您建议的程序中存在一个错误-竞赛条件-

1

2if (semaphore.tryAcquire()) { resource.access(); } else { doSomethingElseInTheMeantime(); } 之间的时间窗口中,另一个线程可能会获取信号量。这就是为什么通常必须围绕阻塞获取功能设计任何信号量实现的原因。另外,您可以使用tryAcquire()函数:

    margin: 0 auto; 
    text-align: center;

“阻止”是什么意思?

通常,操作系统(OS)负责调度线程。如果线程无法获取信号量,则会被操作系统挂起(即被标记为不适合运行,因此OS调度程序会在选择要运行的线程时忽略它),直到可以再次获取信号量为止。