gpt4 book ai didi

c# - CountdownEvent 与 Barrier 的多线程用法?

转载 作者:太空狗 更新时间:2023-10-30 00:59:52 34 4
gpt4 key购买 nike

查看 Barrier 类,它允许 n 个线程在某个时间点会合:

static Barrier _barrier = new Barrier(3);
static void Main()
{
new Thread(Speak).Start();
new Thread(Speak).Start();
new Thread(Speak).Start();
}
static void Speak()
{
for (int i = 0; i < 5; i++)
{
Console.Write(i + " ");
_barrier.SignalAndWait();
}
}
//OUTPUT: 0 0 0 1 1 1 2 2 2 3 3 3 4 4 4

但是 CountdownEvent 类也是如此:

static CountdownEvent _countdown = new CountdownEvent(3);
static void Main()
{
new Thread(SaySomething).Start("I am thread 1");
new Thread(SaySomething).Start("I am thread 2");
new Thread(SaySomething).Start("I am thread 3");
_countdown.Wait(); // Blocks until Signal has been called 3 times
Console.WriteLine("All threads have finished speaking!");
}
static void SaySomething(object thing)
{
Thread.Sleep(1000);
Console.WriteLine(thing);
_countdown.Signal();
}


// output :
I am thread 3
I am thread 1
I am thread 2
All threads have finished speaking!

所以看起来 Barrier 阻塞直到 n 线程相遇而 CountdownEvent 也在阻塞,直到 n 线程发出信号。

(对我来说)从中学习有点困惑,我什么时候应该使用哪个。

问题:

在哪种(现实生活场景)中我应该选择使用 Barrier 而不是 CountdownEvent(反之亦然)?

最佳答案

关于这两者有一些有趣的事情需要注意:

  • CountdownEvent 没有与之关联的显式后操作; Barrier 可以。
  • 一个 CountdownEvent 和一个具有一个阶段的 Barrier 大致等效,因此可以互换使用。
  • Barrier 可以有多个阶段。当每个阶段完成时,执行阶段后操作;该操作完成后,下一阶段开始。

有一个similar question在讨论此行为的 SO 上,但针对 C# 类的 Java 等价物。答案提供了几个示例,这些示例对 C# 等效项有效。

也就是说,考虑一个现实世界的场景:检查 3 个信贷来源以寻找向购房者提供的潜在贷款。假设您在收到所有 3 个信用评分并对其进行评估之前不想做出决定。您可以使用 CountdownEvent(使用 Wait() 之后的代码检查分数)或使用带有分数检查代码操作的单相屏障。

这里 Barrier 是更好的选择:假设信贷员还想检查购房者的 SO 声誉评分(因为专业用户获得更好的信用!)和其他两个社会评分,但是只有在检索到信用评分之后(因为嘿,如果我们不需要的话,我们不想检查社交媒体)。

Barrier 的巧妙之处在于,您可以在单个方法调用中完成各个阶段,从而保持逻辑紧凑和整洁:

var barrier = new Barrier(participantCount: 3, b => LogScoreAndPossiblyEvaluate(b));
var credit = new int[3];
var social = new int[3];

void LogScoreAndPossiblyEvaluate(Barrier b)
{
Log.Info("Got scores for {b.CurrentPhaseNumber == 1 ? "credit" : "social"} phase");
...
if (b.CurrentPhaseNumber == 2 && SomeComplexCalculationWithSixScores() == LoanResult.Approved)
LoanMoney();
}

...

for (int i=0; i<3; i++)
Task.Run(() => {
credit[i] = GetCreditScore(CreditSource(i);
barrier.SignalAndWait();

social[i] = GetSocialScore(SocialSource(i);
barrier.SignalAndWait();

// all phases done at this point
});

关于c# - CountdownEvent 与 Barrier 的多线程用法?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/52521986/

34 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com