gpt4 book ai didi

c# - c# 中的定时器初始化和竞争条件?

转载 作者:太空狗 更新时间:2023-10-29 20:01:24 24 4
gpt4 key购买 nike

我在 Richter 的书上看到这段代码:

The following code demonstrates how to have a thread pool thread calla method starting immediately and then every 2 seconds thereafter:

/*1*/    internal static class TimerDemo
/*2*/ {
/*3*/ private static Timer s_timer;
/*4*/ public static void Main()
/*5*/ {
/*6*/ Console.WriteLine("Checking status every 2 seconds");
/*7*/ // Create the Timer ensuring that it never fires. This ensures that
/*8*/ // s_timer refers to it BEFORE Status is invoked by a thread pool thread
/*9*/ s_timer = new Timer(Status, null, Timeout.Infinite, Timeout.Infinite);
/*10*/ // Now that s_timer is assigned to, we can let the timer fire knowing
/*11*/ // that calling Change in Status will not throw a NullReferenceException
/*12*/ s_timer.Change(0, Timeout.Infinite);
/*13*/ Console.ReadLine(); // Prevent the process from terminating
/*14*/ }
/*15*/ // This method's signature must match the TimerCallback delegate
/*16*/ private static void Status(Object state)
/*17*/ {
/*18*/ // This method is executed by a thread pool thread
/*20*/ Console.WriteLine("In Status at {0}", DateTime.Now);
/*21*/ Thread.Sleep(1000); // Simulates other work (1 second)
/*22*/ // Just before returning, have the Timer fire again in 2 seconds
/*23*/ s_timer.Change(2000, Timeout.Infinite);
/*24*/ // When this method returns, the thread goes back
/*25*/ // to the pool and waits for another work item
/*26*/ }
/*27*/ }

但是,(抱歉),我还是不明白 #7,#8 这几行是什么意思

当然 - 为什么将它初始化(第 9 行)为 Timeout.Infinite(这显然是:“不要启动计时器”)

(我确实理解防止重叠的一般目的,但我相信这里还有一个 GC 竞争条件 pov。)

编辑

命名空间是 System.Threading

最佳答案

我认为这与 GC 无关,而是为了避免竞争条件:

赋值操作不是原子的:首先创建 Timer 对象,然后对其进行赋值。

这是一个场景:

  • new Timer(...) 创建计时器并开始“计数”

  • 当前线程在分配结束前被抢占 => s_timer 仍然为空

  • 计时器在另一个线程上唤醒并调用Status,但初始线程尚未完成赋值操作!

  • Status 访问 s_timer,它是一个null reference => BOOM!

用他的方法是不可能发生的,例如同样的场景:

  • 计时器已创建但未启动

  • 当前线程被抢占

  • 没有任何反应因为计时器还没有开始引发事件

  • 初始线程再次运行

  • 结束分配 => s_timer 引用计时器

  • 计时器安全启动:以后对Status 的任何调用都是有效的,因为s_timer 是一个有效的引用

关于c# - c# 中的定时器初始化和竞争条件?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/17263326/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com