gpt4 book ai didi

c# - 同步线程协程

转载 作者:行者123 更新时间:2023-11-30 22:08:53 24 4
gpt4 key购买 nike

我正在尝试让线程在执行前相互等待,以便它们保持同步。

在我的实际程序中,我有很多 IObjectObserved 对象(在它们自己的线程上)发送事件,我想保持一切同步所以 IObjectListener(在它的自己的线程)可以监听其中一个对象 50 次,然后及时订阅另一个对象以捕获它的第 51 个事件。

我还没有走到那一步,但我认为同步线程是主要问题。我设法通过使用 AutoResetEvent 的两种信号方式实现了这一点。有没有更好的方法来做到这一点?

class Program
{
static EventWaitHandle _ready = new AutoResetEvent(true);
static EventWaitHandle _go = new AutoResetEvent(false);
static EventWaitHandle _ready1 = new AutoResetEvent(true);
static EventWaitHandle _go1 = new AutoResetEvent(false);
static EventWaitHandle _ready2 = new AutoResetEvent(true);
static EventWaitHandle _go2 = new AutoResetEvent(false);

static void Main(string[] args)
{
new Thread(Waiter).Start();
new Thread(Waiter1).Start();
new Thread(Waiter2).Start();
for (; ; )
{
_ready.WaitOne();
_ready1.WaitOne();
_ready2.WaitOne();
Console.WriteLine("new round");
_go.Set();
_go1.Set();
_go2.Set();
}
}

static void Waiter()
{
for (; ; )
{
_go.WaitOne();
Thread.Sleep(1000);
Console.WriteLine("Waiter run");
_ready.Set();
}
}
static void Waiter1()
{
for (; ; )
{
_go1.WaitOne();
Thread.Sleep(5000);
Console.WriteLine("water1 run");
_ready1.Set();
}
}
static void Waiter2()
{
for (; ; )
{
_go2.WaitOne();
Thread.Sleep(500);
Console.WriteLine("water2 run");
_ready2.Set();
}
}
}

最佳答案

你可以稍微简化一下。

  • 您可以使用一个 CountdownEvent 而不是等待 3 个 handle 发出信号。 cde.Wait 将阻塞,直到收到 3 次信号。
  • 您还可以使用 SemaphoreSlim 来释放多个线程,而不是使用 3 个不同的句柄。 sem.Release(3) 将解锁最多 3 个在 sem.Wait() 上阻塞的线程。


static CountdownEvent cde = new CountdownEvent(3);
static SemaphoreSlim sem = new SemaphoreSlim(3);

static void X()
{
new Thread(Waiter).Start();
new Thread(Waiter).Start();
new Thread(Waiter).Start();
for (; ; )
{
cde.Wait();
Debug.WriteLine("new round");

cde.Reset(3);
sem.Release(3);
}
}

static void Waiter()
{
for (; ; )
{
sem.Wait();
Thread.Sleep(1000);
Debug.WriteLine("Waiter run");
cde.Signal();
}
}

请注意,现在所有线程都可以重用相同的代码。


编辑:

如评论中所述,一个线程可能会窃取另一个线程的回合。如果您不想发生这种情况,请输入 Barrier将完成这项工作:

   private static Barrier _barrier;

private static void SynchronizeThreeThreads()
{
_barrier = new Barrier(3, b =>
Debug.WriteLine("new round"));

new Thread(Waiter).Start();
new Thread(Waiter).Start();
new Thread(Waiter).Start();

//let the threads run for 5s
Thread.Sleep(5000);
}
static void Waiter()
{
while(true)
{
Debug.WriteLine("Thread {0} done.", Thread.CurrentThread.ManagedThreadId);
_barrier.SignalAndWait();
}
}

您将 3 名参与者添加到屏障。第一个和第二个到达障碍的参与者(即执行 _barrier.SignalAndWait())将阻塞,直到其余参与者也到达障碍。当所有参与者都到达障碍物时,他们将全部被释放并进行另一轮比赛。

请注意,我向屏障构造函数传递了一个 lambda - 这是“后阶段 Action ”,一个将在所有参与者到达屏障之后以及之前 释放它们。

关于c# - 同步线程协程,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/21972078/

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