找出一个线程是否已经启动?

时间:2012-09-12 19:00:09

标签: c# multithreading .net-4.0 dispatcher polling

我有以下代码:

var x = new Thread(new ThreadStart(Delegate));
x.Start();

这将创建一个新线程并启动它。

如何在没有do while循环的情况下检测到线程X已经开始执行?

5 个答案:

答案 0 :(得分:6)

使用信号量作为互斥锁,或使用自动/手动重置事件。

代码

//Initialize semaphore, set it to BLOCK
ManualResetEvent sema = new ManualResetEvent(false);

void Main()
{
    var x = new Thread(Delegate);
    //Request the system to start the thread.
    //This doesn't mean the CPU will immediately run Delegate method
    //but eventually it will do
    x.Start(sema);

    //Stop here and don't do anything on this thread until the semaphore is FREE
    sema.WaitOne();

    [continued main thread]
}

void Delegate(Semaphore sema){
    //Unblock the semaphore
    sema.Set(1);
    [your code here]
}

深刻解释

多线程背后的原则之一是非确定性。如果你没有使用正确的技术,如上所述,你不能预测在多个线程中完成的操作的行为如果你有这样的方法

void Main()
{
    A();
    B();
    C();
}

然后你确定B在A之前或之后都不会被执行。这同样不适用于多线程。

void Main()
{
    new Thread(A).Start();
    new Thread(B).Start();
    new Thread(C).Start();

    D();
}

在运行A的线程之后,您确定运行B的线程是started,但在多线程中,这意味着不同的东西。从MSDN和每本编程手册开始,启动线程仅仅意味着要求操作系统在内核中分配适当的工具以支持多线程。如果这样做(线程已正确创建并计划执行),则该方法将返回而不会出现错误。可能会发生操作系统以任何顺序运行三个线程,具体取决于几个因素。

因此,如果您将它们调试到控制台(认为每个都执行Console.WriteLine("Hello, I'm thread A/B/C"),您可以在不同的执行中获得任何订单:A,B,C; A,C,B; B,C,A等等

所以你现在想要确保,但确实,确实,在运行D之前,特定或每个线程都已经真正启动。实际上,在许多单核CPU情况下,操作系统应该运行{每个线程之前的{1}}方法。这也是不可预测的!因此,在无法预测A,B和C何时运行后,您无法预测D何时运行!!

显式同步是强制暂停代码执行和等待以使事件发生的技术。信号量释放所描述的事件取决于上下文,所以在你的情况下,你只是告诉主线程“等待代表已经开始,然后随心所欲”:)

替代,低效的方法

使用信号量只是使用无限循环执行以下操作的有效方法

D

使用信号量不会简单地浪费CPU来连续检查某个标志是低还是高

答案 1 :(得分:1)

在最基本的层面上,您可以尝试:

if (((Thread)x).ThreadState==ThreadState.Running){
   // do something interesting
}

答案 2 :(得分:1)

x.ThreadState == System.Threading.ThreadState.Running

答案 3 :(得分:1)

您可以使用Thread.ThreadState属性查找其状态。

答案 4 :(得分:0)

最简单的方法,假设线程是长寿的,就是检查Thread.IsAlive。