信号量是一种编程概念,经常用于解决多线程问题。我对社区的问题是:
什么是信号量,如何使用它?
信号量是一种编程概念,经常用于解决多线程问题。我对社区的问题是:
什么是信号量,如何使用它?
当前回答
假设一辆出租车可以容纳3人(后面)+2人(前面),包括司机。因此,一个信号量一次只允许5个人在一辆车里。 互斥只允许一个人坐在汽车的一个座位上。
因此,互斥量是允许对资源的独占访问(如操作系统线程),而信号量是允许在同一时间访问n个资源。
其他回答
想象一下,每个人都想上厕所而浴室的钥匙是有限的。如果剩下的钥匙不够多,那个人就需要等待。因此,可以将信号量看作是表示不同进程(上厕所的人)可以请求访问的卫生间(系统资源)可用的一组键。
现在想象一下两个过程同时去洗手间。这不是一个好的情况,信号量被用来防止这种情况。不幸的是,信号量是一种自愿机制,进程(我们的上厕所的人)可以忽略它(即,即使有钥匙,有人仍然可以把门踢开)。
二进制/互斥量和计数信号量之间也有区别。
请登录http://www.cs.columbia.edu/~jae/4118/lect/L05-ipc.html查看课堂讲稿。
硬件或软件标志。在多任务系统中,信号量是一个变量,其值表示公共资源的状态。需要资源的进程检查信号量以确定资源状态,然后决定如何继续。
假设一辆出租车可以容纳3人(后面)+2人(前面),包括司机。因此,一个信号量一次只允许5个人在一辆车里。 互斥只允许一个人坐在汽车的一个座位上。
因此,互斥量是允许对资源的独占访问(如操作系统线程),而信号量是允许在同一时间访问n个资源。
信号量的作用类似于线程限制器。
示例:如果您有一个100个线程的池,并且您想执行一些DB操作。如果在给定的时间有100个线程访问数据库,那么在数据库中可能会有锁定问题,所以我们可以使用信号量,一次只允许有限的线程。下面的例子一次只允许一个线程。当一个线程调用acquire()方法时,它将获得访问权限,在调用release()方法后,它将释放访问权限,以便下一个线程获得访问权限。
package practice;
import java.util.concurrent.Semaphore;
public class SemaphoreExample {
public static void main(String[] args) {
Semaphore s = new Semaphore(1);
semaphoreTask s1 = new semaphoreTask(s);
semaphoreTask s2 = new semaphoreTask(s);
semaphoreTask s3 = new semaphoreTask(s);
semaphoreTask s4 = new semaphoreTask(s);
semaphoreTask s5 = new semaphoreTask(s);
s1.start();
s2.start();
s3.start();
s4.start();
s5.start();
}
}
class semaphoreTask extends Thread {
Semaphore s;
public semaphoreTask(Semaphore s) {
this.s = s;
}
@Override
public void run() {
try {
s.acquire();
Thread.sleep(1000);
System.out.println(Thread.currentThread().getName()+" Going to perform some operation");
s.release();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
互斥量只是一个布尔值,而信号量是一个计数器。
两者都用于锁定部分代码,这样就不会有太多线程访问它。
例子
lock.set()
a += 1
lock.unset()
现在,如果lock是一个互斥锁,这意味着无论有多少线程尝试访问受保护的代码片段,它将始终处于锁定或解锁状态(表面下是一个布尔值)。当被锁定时,任何其他线程都会等待它被前一个线程解锁/取消设置。
现在想象一下,如果lock在引擎盖下是一个具有预定义MAX值的计数器(在我们的例子中是2)。然后,如果有两个线程试图访问该资源,那么lock的值将增加到2。如果第三个线程试图访问它,它就会等待计数器低于2,以此类推。
如果lock作为一个信号量的最大值为1,那么它将完全作为一个互斥量。