信号量是一种编程概念,经常用于解决多线程问题。我对社区的问题是:
什么是信号量,如何使用它?
信号量是一种编程概念,经常用于解决多线程问题。我对社区的问题是:
什么是信号量,如何使用它?
当前回答
硬件或软件标志。在多任务系统中,信号量是一个变量,其值表示公共资源的状态。需要资源的进程检查信号量以确定资源状态,然后决定如何继续。
其他回答
@Craig:
信号量是一种锁定 资源,这样才有保证 当执行一段代码时, 只有这段代码可以访问 该资源。这保留了两个线程 从并发访问资源, 这可能会导致问题。
这不仅仅局限于一个线程。信号量可以配置为允许固定数量的线程访问资源。
互斥量只是一个布尔值,而信号量是一个计数器。
两者都用于锁定部分代码,这样就不会有太多线程访问它。
例子
lock.set()
a += 1
lock.unset()
现在,如果lock是一个互斥锁,这意味着无论有多少线程尝试访问受保护的代码片段,它将始终处于锁定或解锁状态(表面下是一个布尔值)。当被锁定时,任何其他线程都会等待它被前一个线程解锁/取消设置。
现在想象一下,如果lock在引擎盖下是一个具有预定义MAX值的计数器(在我们的例子中是2)。然后,如果有两个线程试图访问该资源,那么lock的值将增加到2。如果第三个线程试图访问它,它就会等待计数器低于2,以此类推。
如果lock作为一个信号量的最大值为1,那么它将完全作为一个互斥量。
我已经创建了可视化,这应该有助于理解这个想法。信号量控制多线程环境中对公共资源的访问。
ExecutorService executor = Executors.newFixedThreadPool(7);
Semaphore semaphore = new Semaphore(4);
Runnable longRunningTask = () -> {
boolean permit = false;
try {
permit = semaphore.tryAcquire(1, TimeUnit.SECONDS);
if (permit) {
System.out.println("Semaphore acquired");
Thread.sleep(5);
} else {
System.out.println("Could not acquire semaphore");
}
} catch (InterruptedException e) {
throw new IllegalStateException(e);
} finally {
if (permit) {
semaphore.release();
}
}
};
// execute tasks
for (int j = 0; j < 10; j++) {
executor.submit(longRunningTask);
}
executor.shutdown();
输出
Semaphore acquired
Semaphore acquired
Semaphore acquired
Semaphore acquired
Could not acquire semaphore
Could not acquire semaphore
Could not acquire semaphore
本文中的示例代码
信号量是一种锁定资源的方法,以保证在执行一段代码时,只有这段代码可以访问该资源。这可以防止两个线程并发访问一个资源,从而导致问题。
想象一下,每个人都想上厕所而浴室的钥匙是有限的。如果剩下的钥匙不够多,那个人就需要等待。因此,可以将信号量看作是表示不同进程(上厕所的人)可以请求访问的卫生间(系统资源)可用的一组键。
现在想象一下两个过程同时去洗手间。这不是一个好的情况,信号量被用来防止这种情况。不幸的是,信号量是一种自愿机制,进程(我们的上厕所的人)可以忽略它(即,即使有钥匙,有人仍然可以把门踢开)。
二进制/互斥量和计数信号量之间也有区别。
请登录http://www.cs.columbia.edu/~jae/4118/lect/L05-ipc.html查看课堂讲稿。