为什么以及何时需要使用值为>的信号量? 1?

时间:2014-12-04 21:51:56

标签: multithreading

我很困惑为什么信号量工作时我们有价值> 1以及它们如何保护数据不一致。我知道值为1的信号量与互斥量相同。我们使用互斥锁来保护代码中的关键部分,特别是当我们需要保护数据不一致时(意味着一个线程可以在给定时间内处理数据)。但是价值> 1的信号量; 1允许访问几个线程的相同关键部分......在这里我不明白它是如何工作的。我们如何真正保护我们的数据免于不一致,只允许在给定时间内对其进行有限数量的线程操作。这些线程仍然可以在没有相互排斥的情况下混乱。那么,使用值为>的信号量有什么意义呢? 1?我们什么时候想在互斥体上使用它以及为什么。

谢谢

2 个答案:

答案 0 :(得分:3)

想象一下,您的应用程序有多个与外部服务器通信的线程。该服务器允许您的应用程序随时最多包含五个未完成的请求。如果你真的快速地发出六个请求 - 也就是说,第六个请求发生在服务器响应前五个中的任何一个之前 - 服务器将阻止你的应用程序15分钟。

您可以使用信号量控制它。您将信号量的初始值设置为5.当线程想要请求服务器时,它会等待信号量。等待返回时,信号量计数减1。当信号量计数变为0时,等待的线程将被阻塞,直到某个其他线程释放它为止。

所以你有:

sem = new Semaphore(5); // create semaphore with initial value of 5

当线程想要发出请求时:

sem.Wait();  // waits on semaphore. If there are 5 requests already, this will block
MakeRequest();
GetResponose();
sem.Release();  // release the semaphore, which will increment the count

现在,如果六个线程尝试在很短的时间内发出请求,那么前五个将被允许,第六个线程必须等到其中一个线程调用sem.Release()

真正的问题是为什么你要创建一个最大值小于2的信号量。如果要进行互斥,则应使用互斥锁。值为1的信号量与互斥锁相似,但根本不相同。特别是,互斥锁保证互斥,因为获取锁的线程必须才能释放它。如果某个线程试图释放它没有获取的互斥锁,它将失败。但是使用信号量,任何线程都可以调用Release,即使之前没有调用Wait

答案 1 :(得分:0)

当我们拥有一次可以由多个线程共享的资源时,您使用信号量。 示例:考虑读者编写者的问题。这里的资源是一个可以写入和读取多个位置的缓冲区,我们使用信号量来确保在读取之前有东西可以写入,并且在写入之前有空间可以写入。