3

我有以下代码:

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

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

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

4

5 回答 5

6

使用信号量、互斥体或 Auto/ManualResetEvent。

代码

//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 之前或 C 之后执行。这同样不适用于多线程。

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

    D();
}

您确定运行 Bstarted的线程在运行 A 的线程之后,但是在多线程中,这意味着不同的东西。在 MSDN 和每一本编程书籍中,启动线程仅仅意味着请求操作系统在内核中分配适当的设施以支持多线程。如果这样做了(线程被正确创建并安排执行),则该方法返回而没有错误。操作系统可能会以任意顺序运行三个线程,这取决于几个因素。

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

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

显式同步是一种强制暂停代码执行并等待事件发生的技术。信号量释放所描述的事件取决于上下文,所以在你的情况下,你只是告诉主线程“等待委托开始,然后做任何你想做的事情”:)

替代的、低效的方法

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

volatile bool threadStarted = false;

void Main()
{
    var x = new Thread(Delegate);
    x.Start();

    while (!threadStarted);
    [continued main thread]
}

void Delegate(Semaphore sema){
    threadStarted = true;
    [your code here]
}

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

于 2012-09-12T19:05:07.553 回答
1

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

if (((Thread)x).ThreadState==ThreadState.Running){
   // do something interesting
}
于 2012-09-12T19:05:27.850 回答
1
x.ThreadState == System.Threading.ThreadState.Running
于 2012-09-12T19:05:36.533 回答
1

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

于 2012-09-12T19:05:57.780 回答
0

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

于 2012-09-12T19:04:56.587 回答