【问题标题】:How Thread.Sleep() works?Thread.Sleep() 是如何工作的?
【发布时间】:2019-02-02 22:46:58
【问题描述】:

所以我尝试研究如何使用多线程,但我注意到了一些我不太明白的东西。

在下一段代码中,doo() 似乎在线程完成之前开始运行,尽管 foo 与线程相同:

static void Main(string[] args)
{
    new Thread(new ThreadStart(foo)).Start();
    foo();
    doo();
}

public static void foo()
{

    Console.WriteLine("1");
    Thread.Sleep(3000);
    Console.WriteLine("2");
}

public static void doo()
{
    Console.WriteLine("do");
}

输出是:

1 //线程

1 //foo

2 //foo

做 //doo

2 //线程

假设 doo() 不能在没有 foo() 的情况下开始运行,我们假设最后的“2”输出来自第一个线程。

这怎么可能?虽然 foo() 和 Thread 是相同的函数,所以睡眠时间相同,但为什么 Thread(最先执行)是最后一个完成的呢?

锁定语句

现在,如果我们添加一个 lock 语句,像这样:

static object syncLock = new object();

static void Main(string[] args)
{
    new Thread(new ThreadStart(foo)).Start();
    foo();
    doo();
}

public static void foo()
{
    lock (syncLock)
    {
        Console.WriteLine("1");
        Thread.Sleep(3000);
        Console.WriteLine("2");
    }        
}

public static void doo()
{
    Console.WriteLine("do");
}

输出是:

1 //线程

2 //线程

1 //foo

做 //doo

2 //线程

现在看来 doo() 在 foo() 结束之前就开始运行了!这里发生了什么?其过程和背后的逻辑是什么?

【问题讨论】:

  • no ... 前 1 和 2 来自 foo 而不是线程
  • 不要忘记控制台写入是“缓存的”。
  • @Selvin 为什么?
  • @J.vanLangen “缓存”是什么意思?
  • Console.Out.Flush()

标签: c# multithreading thread-sleep


【解决方案1】:

看,这里实际上有两个线程,在主线程和第二个线程(foo()) .. new Thread(new ThreadStart(foo)).Start(); 执行后将从主线程开始,这意味着该线程(主线程)将尝试调用 foo(),即您的“1 " , 之后,主线程进入睡眠状态,第二个线程启动 foo() ,即第二个“1”,第二个进入睡眠状态。现在主线程将唤醒并完成工作“2”,“ do”,最后一个“2”来自 sec 线程。那是没有锁定的。

使用锁定,主线程将执行 foo() 并且 sec 将被阻塞(“1”,3sec,“2”),当 foo() 解锁时,意味着 sec 线程可以调用 foo(),而当发生这种情况 sec 打印“1”广告进入睡眠状态,现在(当 sec 正在睡眠时 CPU 正在寻找可以执行的线程),因此 CPU exe 执行主线程并打印“do”,然后 sec 将唤醒并打印“ 2"..

【讨论】:

  • 为什么主线程在 foo() 线程之前执行?因为睡觉?
  • 总是在操作系统中你有一个竞争条件,每次当你使用线程工作时,你都需要小心!你不知道女巫线程将首先获得函数或变量。也许 10000 次主线程会更快,但 10001 次线程将首先获得函数。因此,您需要使用信号量或监视器来尝试进行同步。
猜你喜欢
  • 2013-03-13
  • 1970-01-01
  • 1970-01-01
  • 2016-11-09
  • 2016-03-22
  • 2011-04-01
  • 1970-01-01
  • 2023-04-06
  • 1970-01-01
相关资源
最近更新 更多