来自影响另一个线程路径的一个线程的值

我有一个程序,它使用两个客户端线程和一个服务器。 在我的程序中有一点我想在一个线程中的值来影响另一个线程的路径。

更具体地说,我在服务器中有这个代码:

class Handler { public void clientInteraction(Socket connection, bool isFirstThread, Barrier barrier) { string pAnswer = string.Empty; string endGameTrigger = string.Empty; //setup streamReaders and streamWriters while(true) //infinite game loop { //read in a question and send to both threads. pAnswer = sr.ReadLine(); Console.WriteLine(pAnswer); awardPoints(); writeToConsole("Press ENTER to ask another question or enter 0 to end the game", isFirstThread); if(isFirstThread == true) { endGameTrigger = Console.ReadLine(); //this is only assigning to one thread... } barrier.SignalAndWait(); if(endGameTrigger == "0")//...meaning this is never satisfied in one thread { endGame(); } } } } 

布尔值isFirstThread是在线程的构造函数中设置的值,我可以检测哪个线程首先连接到该线程。

是否有某种方式,或者可能是线程方法,允许第二个连接的线程检测到第一个线程中的endGameTrigger已被设置,因此两个线程都正确执行endGame()方法。

最好关注multithreading

  • 如果出于性能/ UI原因而必须启动单独的线程
  • 如果您的代码可能在multithreading环境(如网站)中运行,并且您需要知道当多个线程在同一个类或相同值上运行时它不会中断。

但要谨慎行事。 多个线程的错误使用/处理可能导致代码行为不可预测且不一致。 有些东西会在大部分时间内起作用,然后无法正常工作。 错误很难重现和识别。

话虽这么说,处理multithreading的一个基本概念是确保两个线程不会尝试同时更新相同的值。 它们可能以单个线程无法实现的方式破坏或部分修改值。

实现此目的的一种方法是使用锁定 。

 private object _lockObject = new Object(); private string _myString; void SetStringValue(string newValue) { lock(_lockObject) { _myString = newValue; } } 

您通常只有一个对象存在,只能用作锁。 当一个线程进入该lock块时,它会获取对象的锁定。 如果另一个线程已经锁定该对象,则下一个线程只是等待前一个线程释放锁定。 这可确保两个线程无法同时更新该值。

您希望尽可能减少lock的代码量,以便尽快释放锁。 并且要注意,如果它因多个锁而变得复杂,那么两个线程可以永久地相互阻塞。

对于递增和更新数字,还有一些互锁操作可以为您处理锁定,确保这些操作一次由一个线程执行。

为了好玩,我写了这个控制台应用程序。 它需要一个句子,将其分解为单词,然后使用多个线程将每个单词添加回新的字符串并输出该字符串。

 using System; using System.Threading.Tasks; namespace FunWithThreading { class Program { static void Main(string[] args) { var sentence = "I am going to add each of these words to a string " + "using multiple threads just to see what happens."; var words = sentence.Split(' '); var output = ""; Parallel.ForEach(words, word => output = output + " " + word); Console.WriteLine(output); Console.ReadLine(); } } } 

前两次我运行它,输出字符串正是我开始使用的。 太棒了,它完美无缺! 然后我得到了这个:

I am going to add of these words to a string using multiple threads just to see what happens. each

然后我跑了20多次,无法重复错误。 想象一下,如果这是一个真正的应用程序并且像这样的事情发生了不可预测的事情,即使我一遍又一遍地测试,然后我再也无法让它发生。

所以关键不在于multithreading是邪恶的,而只是为了理解风险,只在需要时引入它,然后仔细考虑如何防止线程相互干扰。

回应Luaan的评论。 我已将endGameTrigger作为private static string endGameTrigger放在Handler类中。 使其成为static字段而不是本地方法变量允许handler类(每个线程)的所有实例访问此变量的最新分配。 非常感谢。