【问题标题】:Multithreading, wrong output多线程,错误输出
【发布时间】:2016-07-04 19:52:23
【问题描述】:

我正在尝试制作一个多线程应用程序。但是输入只有一个线程。但我尝试用三个线程来实现。这是程序:

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

但输出是:见图片:

所以它只显示一个线程。而不是三个线程。

谢谢

这必须是输出:

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.

但如果我这样做:

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

它给出了相同的结果。

如果我这样做:

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.");

同样的结果。只有一个线程。

我是这样尝试的:

  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.");

但结果还是一样。

哦:

这对我有用!!

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.");

【问题讨论】:

  • 你为什么评论do/while循环?您的if 条件使您无需等待结果即可退出
  • 您好,谢谢您的回答。我编辑帖子
  • 您的代码非常适合我,我认为您的操作系统/CPU 设置有问题?
  • 哦,那怎么改呢?谢谢
  • 你好??谁对我的问题投了反对票??我怎么知道它在我的电脑上不起作用?如果它与CPU有关?这真的没做好

标签: c# c#-4.0


【解决方案1】:

您正在创建三个类。每个类都会创建一个新线程,该线程会增加自己的属性。但是,如果 所有数字 都小于 10,则您将退出控制台应用程序。换句话说,如果其中任何一个数字先于其他数字达到 10

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

然后Main() 将结束。在检查该条件之前,无法保证这些计数中的任何一个都会达到 10,更不用说所有三个了。其中一个甚至可以在其他人开始之前达到 10 个。

如果你把它改成这样,你会更接近预期的效果:

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

换句话说,如果其中任何一个小于 10,则继续。当它们都达到 10 时,停止。

您会发现(或已经拥有)的另一件事是,除非您小心,否则多线程应用程序可能会以不可预测的、不一致的方式运行。没有什么比一个程序在 99% 的时间都运行完美,但突然做出不同的事情,然后又按预期运行更令人沮丧的了。 Here's an example 可以测试并查看输出。

【讨论】:

  • 感谢您的回复。我按照你的建议试试。但它给出了相同的结果。
【解决方案2】:

您的 if 语句不正确,根本不起作用。当我使用“while”版本时,您的代码对我有用,只是您检测线程何时完成的策略有问题(甚至可能是您问题的根源)。试试这个代码,看看你的问题是否消失。如果没有,那么您可能会在本地遇到可用内存/cpu/线程池的问题。重新启动计算机并重试:)

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.");
}

【讨论】:

  • 感谢您的回复。看我的评论
  • 所以我重新启动了电脑。但变化不大
  • 如果您调用 Join,则不需要该 while 循环。 Join 会阻塞调用线程(您的主线程),直到您要加入的线程退出。当我在上面粘贴的是 Main() 的整个实现时,向我们展示你的代码输出。此外,您可以查看ThreadPool.GetMaxThreads 在您的计算机上返回的内容。
【解决方案3】:

我找到了解决方案。看我的帖子

【讨论】:

  • 建议 - 确保您知道为什么它以前不起作用。原因是因为这种类型的编程有点棘手,它可能会起作用,但偶尔会不起作用。我认为您得出的结果每次都会起作用(只要顺序无关紧要)。但重要的是要弄清楚为什么而不是通过反复试验得出结果。
  • 当然,你是对的。起初我不明白。但现在我明白了。
猜你喜欢
  • 2013-10-18
  • 1970-01-01
  • 1970-01-01
  • 2013-10-21
  • 1970-01-01
  • 2021-05-30
  • 1970-01-01
  • 2014-01-18
  • 2015-01-20
相关资源
最近更新 更多