gpt4 book ai didi

c# - 等待另一个线程

转载 作者:太空狗 更新时间:2023-10-30 00:01:44 25 4
gpt4 key购买 nike

所以我有这个程序试图在两个不同的线程 thread1 和 thread2 之间建立通信。

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading;

namespace Project1
{
class Class1
{
public static void thread1()
{
Console.WriteLine("1");
Console.WriteLine("t2 has printed 1, so we now print 2");
Console.WriteLine("t2 has printed 2, so we now print 3");
}

public static void thread2()
{
Console.WriteLine("t1 has printed 1, so we now print 1");
Console.WriteLine("t1 has printed 2, so we now print 2");
Console.WriteLine("t1 has printed 3, so we now print 3");
}

public static void Main() {

Thread t1 = new Thread(new ThreadStart(() => thread1()));
Thread t2 = new Thread(new ThreadStart(() => thread2()));
t1.Start();
t2.Start();
t2.Join();
t1.Join();

}

}
}

但是,我希望它发生这样一行:

Console.WriteLine("1");

...首先执行,而 thread2 只是等待这一行被执行。然后并且只有那时它才会打印:

Console.WriteLine("t1 has printed 1, so we now print 1");

打印此行后,然后且仅此后此行:

Console.WriteLine("t2 has printed 1, so we now print 2");

...打印,等等。所以我想更改代码,以便线程相互通信,以便按以下顺序打印行:

            Console.WriteLine("1"); // from t1
Console.WriteLine("t1 has printed 1, so we now print 1"); // from t2
Console.WriteLine("t2 has printed 1, so we now print 2"); // from t1
Console.WriteLine("t1 has printed 2, so we now print 2"); // from t2
Console.WriteLine("t2 has printed 2, so we now print 3"); // from t1
Console.WriteLine("t1 has printed 3, so we now print 3"); // from t2

我明白锁的作用,但它只适用于两个不同的线程在同一个函数上运行的情况。但是,在这里,这两个函数是不同的,因此我不能在这里使用锁。

有什么想法吗?

最佳答案

看来你需要Monitor.WaitMonitor.Pulse .有一个 free eBook Threading 上有很多(可能有很多,但这个对我有帮助)。

您可以使用一个静态对象来锁定,然后让您的线程调用 Monitor.Pulse 来表示它们“轮到他们完成”和 Monitor.Wait “等待他们的下一个回合”。这是使用您的基本代码的示例实现:

public class Class1
{
// Use this to syncrhonize threads
private static object SyncRoot = new object();
// First "turn" goes to thread 1
private static int threadInControl = 1;

public static void thread1()
{
lock(SyncRoot) // Request exclusive access to SyncRoot
{
Console.WriteLine("1");
GiveTurnTo(2); // Let thread 2 have a turn
WaitTurn(1); // Wait for turn to be given to thread 1
Console.WriteLine("t2 has printed 1, so we now print 2");
GiveTurnTo(2); // Let thread 2 have a turn
WaitTurn(1); // Wait for turn to be given to thread 1
Console.WriteLine("t2 has printed 2, so we now print 3");
GiveTurnTo(2); // Let thread 2 have a turn
}
}

public static void thread2()
{
lock(SyncRoot) // Request exclusive access to SyncRoot
{
WaitTurn(2); // Wait for turn to be given to thread 2
Console.WriteLine("t1 has printed 1, so we now print 1");
GiveTurnTo(1); // Let thread 1 have a turn
WaitTurn(2); // Wait for turn to be given to thread 2
Console.WriteLine("t1 has printed 2, so we now print 2");
GiveTurnTo(1); // Let thread 1 have a turn
WaitTurn(2); // Wait for turn to be given to thread 2
Console.WriteLine("t1 has printed 3, so we now print 3");
GiveTurnTo(1); // Let thread 1 have a turn
}
}

// Wait for turn to use SyncRoot object
public static void WaitTurn(int threadNum)
{
// While( not this threads turn )
while (threadInControl != threadNum)
{
// "Let go" of lock on SyncRoot and wait utill
// someone finishes their turn with it
Monitor.Wait(SyncRoot);
}
}

// Pass turn over to other thread
public static void GiveTurnTo(int nextThreadNum)
{
threadInControl = nextThreadNum;
// Notify waiting threads that it's someone else's turn
Monitor.Pulse(SyncRoot);
}

public static void void Main()
{
Thread t1 = new Thread(new ThreadStart(() => Class1.thread1()));
Thread t2 = new Thread(new ThreadStart(() => Class1.thread2()));
t1.Start();
t2.Start();
t2.Join();
t1.Join();
}
}

至于使用lock keyword ,不限于同一个函数内的同步。锁定“保证”单个线程对资源(对象)的独占访问(独占,我的意思是一次只有一个线程可以获得对该资源的锁定,锁定不会阻止其他线程简单地访问对象本身) .

为了简化它,lock(someObject) 就像一个线程排队使用 someOject 然后等待它前面的所有其他线程完成轮到在继续之前。当一个线程离开锁定语句的范围时,它结束它的“转向”(除非您添加诸如 Monitor.PulseMonitor.Wait 之类的东西)。

关于c# - 等待另一个线程,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/11990651/

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