-2

I am trying to make a multithreading application. But the input is onely with one thread. But I try to make it with three threads. THis is the program:

class MyThread
    {
        public int Count;
        public Thread Thrd;
        public MyThread(string name)
        {
            Count = 0;
            Thrd = new Thread(this.Run);
            Thrd.Name = name;
            Thrd.Start();
        }
        // Entry point of thread.
        void Run()
        {
            Console.WriteLine(Thrd.Name + " starting.");
            do
            {
                Thread.Sleep(500);
                Console.WriteLine("In " + Thrd.Name +
                ", Count is " + Count);
                Count++;
            } while (Count < 10);
            Console.WriteLine(Thrd.Name + " terminating.");
        }
    }
    class Program
    {
        static void Main(string[] args)
        {

            Console.WriteLine("Main thread starting.");
            // Construct three threads.
            MyThread mt1 = new MyThread("Child #1");
            MyThread mt2 = new MyThread("Child #2");
            MyThread mt3 = new MyThread("Child #3");
            while (true)
            {
                Console.Write(".");
                Thread.Sleep(100);
                if (mt1.Count < 10 && mt2.Count < 10 &&  mt3.Count < 10)
                {
                    break; 
                }
                Console.WriteLine("Main thread ending.");
            }
            //do
            //{
            //    Console.Write(".");
            //    Thread.Sleep(100);
            //} 
            //while (mt1.Count < 10 && mt2.Count < 10 &&  mt3.Count < 10);
            //Console.WriteLine("Main thread ending.");
           // Console.ReadKey();
        }
    }

But the output is: see image: enter image description here

So it onely displays one thread. And not three threads.

THank you

This has to be the output:

Main thread starting.
.Child #1 starting.
Child #2 starting.
Child #3 starting.
....In Child #1, Count is 0
In Child #2, Count is 0
In Child #3, Count is 0
.....In Child #1, Count is 1
In Child #2, Count is 1
In Child #3, Count is 1
.....In Child #1, Count is 2
In Child #2, Count is 2
In Child #3, Count is 2
.....In Child #1, Count is 3
In Child #2, Count is 3
In Child #3, Count is 3
.....In Child #1, Count is 4
In Child #2, Count is 4
In Child #3, Count is 4
.....In Child #1, Count is 5
In Child #2, Count is 5
In Child #3, Count is 5
.....In Child #1, Count is 6
In Child #2, Count is 6
In Child #3, Count is 6
.....In Child #1, Count is 7
In Child #2, Count is 7
In Child #3, Count is 7
.....In Child #1, Count is 8
In Child #2, Count is 8
In Child #3, Count is 8
.....In Child #1, Count is 9
Child #1 terminating.
In Child #2, Count is 9
Child #2 terminating.
In Child #3, Count is 9
Child #3 terminating.
Main thread ending.

But if I do it like this:

static void Main(string[] args)
        {

            Console.WriteLine("Main thread starting.");
            // Construct three threads.
            MyThread mt1 = new MyThread("Child #1");
            MyThread mt2 = new MyThread("Child #2");
            MyThread mt3 = new MyThread("Child #3");
            //while (true)
            //{
            //    Console.Write(".");
            //    Thread.Sleep(100);
            //    if (mt1.Count < 10 && mt2.Count < 10 &&  mt3.Count < 10)
            //    {
            //        break; 
            //    }
            //    Console.WriteLine("Main thread ending.");
            //}
            do
            {
                Console.Write(".");
                Thread.Sleep(100);
            }
            while (mt1.Count < 10 && mt2.Count < 10 && mt3.Count < 10);
            Console.WriteLine("Main thread ending.");
            Console.ReadKey();
        }

It gives the same result.

If I do this:

Console.WriteLine("Main thread starting.");
            // Construct three threads.
            MyThread mt1 = new MyThread("Child #1");
            MyThread mt2 = new MyThread("Child #2");
            MyThread mt3 = new MyThread("Child #3");

            mt1.Thrd.Join();
            mt2.Thrd.Join();
            mt3.Thrd.Join();

            do
            {
                Console.Write(".");
                Thread.Sleep(100);
            } while (mt1.Thrd.IsAlive &&  mt2.Thrd.IsAlive &&  mt3.Thrd.IsAlive);
            Console.WriteLine("Main thread ending.");

Same result. Just one thread.

I try it like this:

  static void Main(string[] args)
        {
            Console.WriteLine("Main thread starting.");
            // Construct three threads.
            MyThread mt1 = new MyThread("Child #1");
            MyThread mt2 = new MyThread("Child #2");
            MyThread mt3 = new MyThread("Child #3");

            mt1.Thrd.Join();
            mt2.Thrd.Join();
            mt3.Thrd.Join();

            do
            {
                Console.Write(".");
                Thread.Sleep(100);
            } while (mt1.Count < 10 || mt2.Count < 10 || mt3.Count < 10);
            Console.WriteLine("Main thread ending.");

But still the same result.

oh:

This worked for me!!

Console.WriteLine("Main thread starting.");
            // Construct three threads.
            MyThread mt1 = new MyThread("Child #1");
            MyThread mt2 = new MyThread("Child #2");
            MyThread mt3 = new MyThread("Child #3");

            mt1.Thrd.Join();
            mt2.Thrd.Join();
            mt3.Thrd.Join();

            do
            {
                Console.Write(".");
                Thread.Sleep(100);
            } while (mt1.Thrd.IsAlive || mt2.Thrd.IsAlive || mt3.Thrd.IsAlive);
            Console.WriteLine("Main thread ending.");
InfinityGoesAround
  • 1,011
  • 4
  • 17
  • 31
  • Why did you comment the `do/while` loop? Your `if` condition makes you exit without waiting for the result – Kevin Gosse Jul 04 '16 at 19:59
  • Hi, thank you for your answer. I edit the post – InfinityGoesAround Jul 04 '16 at 20:02
  • Your code works perfectly for me, I'd think its an issue on your end with OS/CPU settings? – prospector Jul 04 '16 at 20:05
  • Oh, but how to change it then? Thank you – InfinityGoesAround Jul 04 '16 at 20:05
  • Hello?? who down voted my question?? How can I know that it on my pc doesn't work?? If it has to do with CPU?? This is realy not done – InfinityGoesAround Jul 04 '16 at 20:13
  • I didn't downvote. It's a not a bad question, conceptually. It does require the reader to go through quite a bit (including images and commented-out code) before they can actually understand what the problem is. If you spell it out in more detail - why is this happening before this? Why isn't this line finishing - it makes it a little easier to process and answer. – Scott Hannen Jul 04 '16 at 20:23
  • It's not your CPU settings. Unless you're doing something really out there, .NET code is essentially going to run the same on any PC. Multithreading can be problematic and unpredictable, but it's going to be equally so on different computers. – Scott Hannen Jul 04 '16 at 20:28
  • @Scott. Yes. But you explain what I do wrong in my question. But just down vote without any improvement. That is easy - every body can do that without any reason. If you don't explain what would be wrong, How can I correct my answer? You help me. Because you explain it to me. – InfinityGoesAround Jul 04 '16 at 20:31
  • I would like to point out that in your screenshot, which clearly had some buggy thread exit checking code, VS clearly indicates that your threads were still running when the program exited (259). So it's not that they aren't starting, it's more that they aren't running/finishing. Perhaps [ThreadPool.GetMaxThreads](https://msdn.microsoft.com/en-us/library/system.threading.threadpool.getmaxthreads(v=vs.110).aspx) gives a clue? – Trevor Ash Jul 04 '16 at 20:33
  • Thank you all!! But I found the solution – InfinityGoesAround Jul 04 '16 at 20:36
  • Here's a DotNetFiddle where I got it working. [https://dotnetfiddle.net/vGVIfW](https://dotnetfiddle.net/vGVIfW). I just had to reduce the sleep time because .NET fiddle only allows a certain number of seconds before it terminates a program. – Scott Hannen Jul 04 '16 at 20:44
  • [Here's another demo](https://dotnetfiddle.net/CbBPbE). I wrote this just for fun because it demonstrates how a multithreaded application can behave the exact same way over and over, leading us to think that we know what it's going to do. But if you run it 5, 10, or 20 times eventually you're going to get a slightly different result. – Scott Hannen Jul 04 '16 at 21:33
  • Thank you for all your effort. And the examples. It is very nice of you.You explain it at least :) – InfinityGoesAround Jul 04 '16 at 21:45

3 Answers3

2

You're creating three classes. Each class creates a new thread which increments its own property. But you're exiting the console app if all of the numbers are less than 10. In other words, if any one of these reaches 10 before the others

while (mt1.Count < 10 && mt2.Count < 10 && mt3.Count < 10);

then the Main() will end. There's no guarantee that any one of those counts will reach 10 before that condition is checked, let alone all three of them. One of them could reach 10 before the others even start.

You would get closer to intended affect if you change it to this:

while (mt1.Count < 10 || mt2.Count < 10 || mt3.Count < 10);

In other words, if any one of them is less than 10, keep going. When they all reach 10, stop.

Something else you'll find (or already have) is that unless you're careful, multithreaded apps can behave in unpredictable, inconsistent ways. There's nothing more frustrating than a program that runs perfectly 99% of the time but then suddenly does something different, and then it works as expected again. Here's an example where you can test and see the output.

Community
  • 1
  • 1
Scott Hannen
  • 27,588
  • 3
  • 45
  • 62
0

The if statement you have is incorrect and doesn't work at all. When I used the "while" version, your code works for me except that your strategy to detect when the threads have finished is buggy (perhaps a source of your issue even). Try this code and see if your problems go away. If not, then you might be running into issues locally with available memory/cpu/thread pools. Reboot your computer and try again :)

static void Main(string[] args)
{
    Console.WriteLine("Main thread starting.");

    MyThread mt1 = new MyThread("Child #1");
    MyThread mt2 = new MyThread("Child #2");
    MyThread mt3 = new MyThread("Child #3");

    mt1.Thrd.Join();
    mt2.Thrd.Join();
    mt3.Thrd.Join();

    Console.WriteLine("Main thread ending.");
}
Trevor Ash
  • 623
  • 4
  • 8
  • Thank you for your reply. See my comment – InfinityGoesAround Jul 04 '16 at 20:16
  • So I rebooted the pc. But not so much change – InfinityGoesAround Jul 04 '16 at 20:24
  • You don't need that while loop if you're calling Join. Join blocks the calling thread (your main thread) until the thread you're joining to exits. Show us the output of your code when what I pasted above is the entire implementation for Main(). Also, you might look into what [ThreadPool.GetMaxThreads](https://msdn.microsoft.com/en-us/library/system.threading.threadpool.getmaxthreads(v=vs.110).aspx) returns on your computer. – Trevor Ash Jul 04 '16 at 20:31
0

I found the solution. See my post

InfinityGoesAround
  • 1,011
  • 4
  • 17
  • 31
  • Suggestion - make sure you know why it didn't work before. The reason is that because this type of programming is a little trickier, it might work, but then once in a while not work. I think the result you arrived at will work every time (as long as the sequence doesn't matter.) But it's important to figure out why vs. arriving at it by trial and error. – Scott Hannen Jul 04 '16 at 20:55
  • Ofcourse, you are right. At first I didn' t understand. But now I understand it better. – InfinityGoesAround Jul 04 '16 at 20:58