当前位置: 首页 > 知识库问答 >
问题:

信号量如何从另一个线程释放?

楚权
2023-03-14

据我所知,线程可以释放信号量,而无需首先使用WaitOne获取锁。

所以,如果我们有线程A、B和C以及一个信号量,A和B调用WaitOne,得到一个锁,然后开始做他们的工作<线程C出现了,只需在信号量上调用Release。

这应该将信号量的计数增加1。这是否意味着信号量将终止A或B,或者只允许第三个线程获取锁并在其池中有3个线程,即使最大值为2?

共有2个答案

艾子石
2023-03-14

您可以将信号量视为阻塞队列的特例:信号量的“计数”是队列中的项目数,但项目本身不包含任何信息。正如允许任何线程将项目放入阻塞队列,允许任何线程将项目取出一样,任何线程都可以增加或减少信号量的计数。

姬乐
2023-03-14

考虑

var semaphore = new SemaphoreSlim(2);

这意味着此时的信号量只有2个执行槽,但您必须记住,它只是执行槽的初始数量(对于并发授予的请求)。

因此,如果我们将A、B、C线程生成一个具有2个执行槽的信号量,那么前两个线程将被执行,C线程将排队,直到代码中的其他线程发出信号,再添加一个执行槽就可以了。

当有人说可以执行队列中的下一个线程时,无论其他线程如何,都将执行C。

(正如我在@dmitri-nesteruk的课程中看到的)

可用执行槽的总数由CurrentCount表示。

每次线程想要执行时,它都会询问信号量是否有可用的执行槽(使用MONtCount

使信号量如此混乱的是,CurrentCount的值可以减少也可以增加。

>

每次在代码中的其他地方调用发布(1)时,它会增加一个(或多个),这意味着还有一个可用的执行槽,所以队列中信号量中的第一个线程正在执行(它不会终止其他线程)。

在本例中,我们生成了3个线程,但只会执行前两个线程,直到有人对信号量说,他可以通过使用发布(1)增加当前计数来释放另一个执行槽。

for (int i = 0; i < 3 ; i++)
{
    Task.Factory.StartNew(() => 
    {
        Console.WriteLine($"Spawning task: {Task.CurrentId}");
        semaphore.Wait(); //CurrentCount--
        Console.WriteLine($"Executing task: {Task.CurrentId}");
    });
}


while (semaphore.CurrentCount <= 2)
{
    Console.ReadKey();
    Console.WriteLine("Key pressed");
    semaphore.Release(1); //CurrentCount++
}
Spawning task: A
Spawning task: B
Spawning task: C
Executing task: A
Executing task: B
.....
Key pressed
Executing task: C
 类似资料:
  • 我正在考虑一个语句的示例“在一个线程中获取许可证,然后从另一个线程中释放”。 我对信号量的理解是,它维护一组许可。Thread应在通过临界截面之前获得许可证,然后许可证递减1。一旦Thread完成临界截面,它将释放许可证,许可证将增加1<示例: 1。ATM机,配备一名保安,根据机器的可用性允许人们使用。机器越多,许可证就越多。一位客户购买了一台ATM机,完成后将其释放 2。银行的柜台,如果柜台空闲

  • 问题内容: 我在Java中的线程上有些挣扎,我有三个线程- 线程1,线程2和线程3。那些启动时正在执行某些任务,我想通过thread1停止这两个线程。我将thread1放在,然后停止两个线程,但是两个线程的进程仍在运行。你有什么想法吗? 问题答案: 您如何试图阻止他们??警告此方法已弃用。 而是考虑对线程1使用某种标志来与线程2和3通信,它们应该停止。实际上,您可能会使用interrupts。 下

  • 我有一个应用程序,它在一个单独的线程中的while循环中重复运行一些东西,直到用户触发关闭信号。我可以通过在工作线程中设置(易失性)布尔字段,将信号从主线程发送到工作线程,但是否有其他关闭/中断线程的方法,例如通过“java”中的任何实用程序。util。并发'? 我尝试调用ExecutorService的shutdown()或shutdownNow()方法,但它们无法停止工作线程。同时调用shut

  • 这是进程2中的代码块,它应该捕捉信号量,但没有 因此,这个想法是--这个进程2应该在另一个进程的post/wait之间获得seemaphore--此时,共享的mem段中有数据,并且不是空的。然而,相反,它在另一个进程的最后捕获信号量,这时它已经清空了sahred内存段并删除了其中的任何数据。 我做了很多问题解决,并确认a)每个进程中的信号量都是相同的信号量b)进程1在某个时候会增加信号量,然后捕获

  • 头文件 semaphore.h sys/stat.h fcntl.h 常用函数 函数 说明 [[sem_open sem_open]] 打开一个有名信号量 [[sem_close sem_close]] 关闭一个信号量 [[sem_unlink sem_unlink]] 删除一个信号量 [[sem_post sem_post]] 【V操作】释放操作:信号量的值加1 [[sem_wait sem_w

  • 问题内容: 亲爱的大家,我遇到了挥杆相关的问题。由于违反公司政策,我无法共享代码,因此我将尽力解释该问题。 简而言之,我创建了一个扩展包含JLabel的JWindow的类。JLabel的文本是通过计时器对象随机更新的,该计时器对象使用scheduleAtFixedRate方法每50毫秒实例化一个TimerTask。JLabel中的值是通过在一个单独的线程(称为传输线程)中调用一个方法来检索的,该线