【问题标题】:Understanding Semaphores in C#理解 C# 中的信号量
【发布时间】:2021-12-23 16:43:19
【问题描述】:

我正在尝试理解用 C# 编写的一段代码:

static Semaphore _transactionReceived;
static TransactionsSession _transactionsSession;

static void StartTransactionsStream()
{
    WriteNewLine("Starting transactions stream ...");

    _transactionsSession = new TransactionsSession(AccountID);
    _transactionReceived = new Semaphore(0, 100);
    _transactionsSession.DataReceived += OnTransactionReceived;

    _transactionsSession.StartSession();

    bool success = _transactionReceived.WaitOne(10000);

    if (success)
        WriteNewLine("Good news!. Transactions stream is functioning.");
    else
        WriteNewLine("Bad news!. Transactions stream is not functioning.");
}

但我无法理解代码周期中与 Sempahore 类有关的情况,尤其是以下几行的作用:

_transactionReceived = new Semaphore(0, 100);

_transactionReceived.WaitOne(10000)

正在做。

我已经查看并(重新)查看了System.Threading.Semaphoredocumentation,并且我看到构造函数 “初始化 Semaphore 类的新实例,指定初始条目数和最大并发条目数." 但是当有0 条目时这意味着什么?

另外,我看到WaitOne(int32)调用“阻塞当前线程,直到当前WaitHandle接收到信号,使用32位有符号整数来指定时间间隔,以毫秒为单位。”但是再次,WaitOne 在代码周期的上下文中意味着什么?

任何关于如何执行的指针或一般 cmets 都会有所帮助。 非常感谢!

【问题讨论】:

  • 查看哪些其他代码段使用了相同的信号量。信号量用于同步和信令。我希望 DataReceived 处理程序是信号量的信号。
  • 我假设_transactionsSession.StartSession(); 获取信号量 100 次。因为 Semaphore 最多可以获取 100 次,这意味着_transactionReceived.WaitOne(10000); 被阻塞,因为没有免费的请求可以让 Semaphore 授予。事务流在释放信号量一次时“正在运行”——这并不意味着操作已完成,只是很可能已经完成了 100 分之一的事情
  • 关于 initialCount 解释的有用答案:stackoverflow.com/a/9363524/255259

标签: c# multithreading semaphore


【解决方案1】:

但是当条目为 0 时是什么意思呢?

正是如此; Semaphore 目前没有超过 100 个条目。

如果您使用new Semaphore(1, 100); 构建了Semaphore,那么将有1 个条目,另外还有99 个。

需要Semaphore.Release() 才能有 100 个剩余条目。

WaitOne 在代码周期的上下文中是什么意思?

如果 Semaphore 有可用条目,即当前条目数不是 100,则它立即返回 true

否则,它会阻塞当前线程,直到条目可用(可能由另一个线程调用Semaphore.Release()),此时该方法返回true

如果您指定int millisecondsTimeout,这是Semaphore 将阻塞并等待条目被释放的最长时间。

如果超时,该方法返回false

【讨论】:

    【解决方案2】:

    信号量说明

    Semaphore 是一个同步对象,它允许在代码部分中实现有限度的并行性。

    为简单起见,假设您在代码块上实例化一个全新的信号量(没有共享实例、全局变量或其他邪恶)。由于多个线程可以同时执行同一段代码,因此信号量保证其中只有x可以同时执行同一块。

    将线程视为工人。并非巧合,线程通常被称为工作线程

    但是当条目为 0 时是什么意思呢?

    信号量处于红色状态,所以没有人可以执行特定的代码段直到某个线程解锁信号量。您可以创建一个 GUI,其中多个线程竞争同一操作,但通过按下按钮解锁信号量并允许一个线程运行。

    但是,在代码循环的上下文中,WaitOne 是什么意思?

    表示发生以下情况之一

    • 信号量处于 绿色 状态,即具有许可。线程不等待,信号量递减,操作继续
    • 信号量处于 红色 状态,即没有可用的许可
      • WaitOne 要么等待 10 秒 (10000 毫秒),因为在此期间没有可用的许可
      • 或者其他人解锁信号量和调用WaitOne的线程很好去

    关于您的代码

    必须有其他释放信号量的方法,但示例中没有显示。事实上,您在等待的地方有一个 red 信号量,但显然没有人释放它。我相信这两行之一隐藏了Semaphore.Release 方法

     _transactionsSession.DataReceived += OnTransactionReceived;
    
     _transactionsSession.StartSession();
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-09-23
      • 2011-01-29
      相关资源
      最近更新 更多