A value from one thread influencing the path of another thread

橙三吉。 提交于 2019-11-26 18:43:33

问题


I have a program which uses two client threads and a server. There is a point in my program where I want a value in one thread to influence the path of another thread.

More specifically, I have this code in the server:

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();
            }           

        }
    }
}   

The boolean value isFirstThread is a value set up in the constructor of the thread to which I can detect which thread was connected first.

Is there some way, or perhaps a threading method, that will allow the second connected thread to detect that the endGameTrigger in the first thread has been set and therefore both threads execute the endGame() method properly.


回答1:


It's best to be concerned with multithreading

  • If it's absolutely necessary to start a separate thread for performance/UI reasons
  • If your code may be running in a multithreaded environment (like a web site) and you need to know that it won't break when multiple threads operate on the same class or same values.

But exercise extreme caution. Incorrect use/handling of multiple threads can cause your code to behave unpredictably and inconsistently. Something will work most of the time and then not work for no apparent reason. Bugs will be difficult to reproduce and identify.

That being said, one of the essential concepts of handling multithreading is to ensure that two threads don't try to update the same value at the same time. They can corrupt or partially modify values in ways that would be impossible for a single thread.

One way to accomplish this is with locking.

private object _lockObject = new Object();
private string _myString;

void SetStringValue(string newValue)
{
    lock(_lockObject)
    {
        _myString = newValue;
    }
}

You generally have an object that exists only to serve as a lock. When one thread enters that lock block it acquires a lock on the object. If another thread already has a lock on that object then the next thread just waits for the previous thread to release the lock. That ensures that two threads can't update the value at the same time.

You want to keep the amount of code inside the lock as small as possible so that the lock is released as soon as possible. And be aware that if it gets complicated with multiple locks then two threads can permanently block each other.

For incrementing and updating numbers there are also interlocked operations that handle the locking for you, ensuring that those operations are executed by one thread at a time.

Just for fun I wrote this console app. It takes a sentence, breaks it into words, and then adds each word back onto a new string using multiple threads and outputs the string.

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();
        }
    }
}

The first two times I ran it, the output string was exactly what I started with. Great, it works perfectly! Then I got this:

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

Then I ran it 20 more times and couldn't repeat the error. Just imagine the frustration if this was a real application and something unpredictable like this happened even though I tested over and over and over, and then I couldn't get it to happen again.

So the point isn't that multithreading is evil, but just to understand the risks, only introduce it if you need to, and then carefully consider how to prevent threads from interfering with each other.




回答2:


In response to Luaan's comment. I have put the endGameTrigger as private static string endGameTrigger in the Handler class. Making it a static field instead of a local method variable allows all instances of the handler class (each thread) access to this variable's most recent assignation. Many thanks.



来源:https://stackoverflow.com/questions/36376590/a-value-from-one-thread-influencing-the-path-of-another-thread

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!