这个同步线程怎么样? [英] what about this Synchronization threading ?

查看:72
本文介绍了这个同步线程怎么样?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

为什么在第一个代码中编译器到达结束循环,但第二个不能???



第一个:

why in first code the compiler reach to end loop ,but the second cannot ???

First:

class Program
{
    static bool Mark = true;

    static void Main(string[] args)
    {
        Program pro = new Program();

        Thread ob = new Thread(TestThread);
        ob.Start();

        Thread.Sleep(20);

        Mark = false;
        Console.WriteLine("End prog");

    }
    static void TestThread()
    {
        Console.WriteLine("start loop");
        while (Mark) { }
        Console.WriteLine("End loop");
    }
}



秒:


second:

class Program
    {
        bool Mark = true;

        static void Main(string[] args)
        {
            Program pro=new Program();
            
            Thread ob = new Thread(TestThread);
            ob.Start(pro);

            Thread.Sleep(20);

            pro.Mark = false;
            Console.WriteLine("End prog");

        }
        static void TestThread(object o)
        {
            Program X = (Program)o;
  
            Console.WriteLine("start loop");
            while (X.Mark){ }
            Console.WriteLine("End loop");
        }        
    }

推荐答案

当然,两种变体都可以使用,并且线程达到End loop 。您刚刚使用 Thread.Start 的参数来传递处理实例变量所需的类实例。是的,我测试了它,以防万一。



尽管如此,这种编码很大程度上滥用了线程。首先,你不应该在没有同步的情况下使用任何共享变量(在你的情况下 Mark ),这可能是一个简单的锁定:

< a href =http://msdn.microsoft.com/en-us/library/c5kehkcz.aspx> http://msdn.microsoft.com/en-us/library/c5kehkcz.aspx [< a href =http://msdn.microsoft.com/en-us/library/c5kehkcz.aspxtarget =_ blanktitle =New Window> ^ ]。



但是,我知道你这样做只是为了学习,这实际上是一件好事。但是你应该理解这种滥用行为。



即使你用 ParametrizedThreadStart 做什么是常见的做法,我想这太蹩脚了。谁告诉你线程方法( TestThread ,在你的情况下)应该是一个静态方法? (我知道,此时MSDN文档可能看起来不太清楚。)这不是C ++。而且,由于您可以使用即时方法,您可以通过this传递您需要的任何内容。它将消除对型箱的需求,这当然是有潜在危险的。你需要做的就是包装一个线程。它提供了许多其他好处,非常重要。请看我过去的答案:

如何将ref参数传递给线程 [ ^ ],

更改线程(生产者)启动后的参数 [ ^ ],

C#中的多线程 [ ^ ],

AsyncCallback和Threadings [ ^ ]。



另外,看看你的而(X.Mark){} 。这被称为旋转等待,这是一件非常糟糕的事情。您是否理解它简单的声明需要100%的CPUT(或某些CPU核心)一段时间,没有任何用处?通常,人们会在循环中做一些或多或少随意睡眠的肮脏工作。但是,这仍然不是一个好的解决方案:如果你定期检查标志,但很少,你会错过需要退出线程的事件,但如果经常检查,则会浪费CPU时间。没有真正的最佳选择。理想情况下,您应该进行硬件中断。可能吗?是的,在这种情况下,通过 Thread.Abort

http://msdn.microsoft.com/en-us/library/system.threading.thread.abort.aspx [ ^ ]。



然而,这可能是一个非常危险的方法,除非你非常清楚它是如何工作的,你怎么能以节省的方式使用这种技术。实际上,没有多少人理解这一点。大多数成员可能会建议在所有情况下使用合作方法,但这是一个非常复杂的问题。无论如何, Thread.Abort 与旧讨厌的 TerminateThread >无关。请看我过去的答案,我试着解释一下:

正确关闭dll中的线程 [ ^ ],

从专用线程创建流程的问题 [ ^ ]。



其实,因为你的 TestThread 在等待期间根本不做任何事情,你可以使用等待状态通过

Of course, both variants will work, and the thread reaches "End loop". You just used parameter of the Thread.Start to pass the class instance needed to work with the instance variable. Yes, I tested it, just in case.

Nevertheless, such kind of coding is a huge abuse of threading. First of all, you should never use any shared variables (Mark in both your cases) without synchronization, which could be a simple lock:
http://msdn.microsoft.com/en-us/library/c5kehkcz.aspx[^].

However, I understand that you do it just for the purposes of study, which is actually a good thing. But you should understand the abuse.

Even though what you do with ParametrizedThreadStart is a common practice, I think this is lame. Who told you that the thread method (TestThread, in your case) should be a static method? (I know, MSDN documentation may look unclear at this point.) This is not C++. And, as you can use an instant method, you can pass whatever you need through "this". It will eliminate the need for type case, which is of course potentially dangerous. All you need to do is to wrap a thread. It gives a lot of other benefits, really important ones. Please see my past answers:
How to pass ref parameter to the thread[^],
Change parameters of thread (producer) after it is started[^],
MultiThreading in C#[^],
AsyncCallback and Threadings[^].

Also, look at your while (X.Mark) { }. This is called spin wait, a really bad thing. Do you understand that it simple statement takes 100% of the CPUT (or some CPU core) for a while, doing nothing useful? Usually, people do such dirty work with some more or less arbitrary sleep in the loop. However, this is still not a good solution: if you check up the flag periodically, but rarely, you miss the event where you need to exit the thread, but if you check up frequently, you waste CPU time. There is no real optimum. Ideally, you should do in on hardware interrupt. Is it possible? Yes, in this case, through Thread.Abort:
http://msdn.microsoft.com/en-us/library/system.threading.thread.abort.aspx[^].

However, this can be a really dangerous approach, unless you know very well how it works and how can you use this technique in a save way. Actually, not many understand that. Most members will probably recommend using cooperative approach in all cases, but this is a very complex matter. Anyway, Thread.Abort has nothing to do with old nasty TerminateThread> Please see my past answers where I try to explain that:
Close correcly the thread inside a dll[^],
Problem with creating Process from dedicated thread[^].

Actually, as your TestThread does not do anything at all during wait, you can use wait state through
class Program {

     static ManualResetEvent eventHandle = new ManualResetEvent(false);

     static void Main(string[] args) {
         Program pro = new Program();
         Thread ob = new Thread(pro.TestThread);
         ob.Start();
         Thread.Sleep(2000);
         eventHandle.Set();
         Console.WriteLine("End prog");
     } //Main

     void TestThread() {
         Console.WriteLine("start loop");
         eventHandle.WaitOne();
         Console.WriteLine("End loop");
     } //TestThread

 } // class Program





然而,在实践中,它没有多大意义,因为 - 为什么我们需要一个在退出之前什么也不做的线程,为什么不立即退出?只写结束循环?然而,最后一个声明可以做一些重要的事情,所以这种情况是可能的,但相对罕见。事件等待处理程序有利于其他目的:通过使用等待状态而不使用任何CPU时间来限制某些线程(暂停而不使用已弃用且危险的 Thread.Pause )。我在过去的答案中解释了这一点:

暂停运行线程 [ ^ ],

线程中的ManualResetEvent和AutoResetEvent [ ^ ],

使代码线程安全 [ ^ ]。



-SA



In practice, however, it makes little sense, because — why would we need a thread which does nothing before exiting, why not exit immediately? Only to write "End loop"? However, this last statement can do something important, so such cases are possible, but relatively rare. The event wait handlers are good for other purposes: to throttle some thread (pause without using deprecated and dangerous Thread.Pause) by using the wait state without using any CPU time. I explained it in these past answers:
pause running thread[^],
ManualResetEvent and AutoResetEvent in Thread[^],
Making Code Thread Safe[^].

—SA


这篇关于这个同步线程怎么样?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆