Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/codeigniter/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 当存在上下文切换时,获取锁的开销是否取决于操作系统计时器分辨率?_C#_Multithreading_Locking_Overhead_Context Switching - Fatal编程技术网

C# 当存在上下文切换时,获取锁的开销是否取决于操作系统计时器分辨率?

C# 当存在上下文切换时,获取锁的开销是否取决于操作系统计时器分辨率?,c#,multithreading,locking,overhead,context-switching,C#,Multithreading,Locking,Overhead,Context Switching,假设线程1尝试使用lock(lockObj)语句获取lockObj对象上的锁,但在线程1尝试获取该对象上的锁时,该对象已被线程2锁定。线程1会阻塞,对吗 现在假设在这个阻塞期间,有一个上下文切换,因为还有其他线程和应用程序等待运行。线程1再次处于运行状态并能够获取锁之前所用的时间是否取决于操作系统计时器分辨率(例如:Windows 7上的默认值为15.6毫秒) 如果上述问题的答案是肯定的,那么我还有一个疑问: 很容易创建一个简单的程序来测试线程的平均开销。Sleep(1)使用Stopwatch并

假设线程1尝试使用
lock(lockObj)
语句获取lockObj对象上的锁,但在线程1尝试获取该对象上的锁时,该对象已被线程2锁定。线程1会阻塞,对吗

现在假设在这个阻塞期间,有一个上下文切换,因为还有其他线程和应用程序等待运行。线程1再次处于运行状态并能够获取锁之前所用的时间是否取决于操作系统计时器分辨率(例如:Windows 7上的默认值为15.6毫秒)

如果上述问题的答案是肯定的,那么我还有一个疑问:

很容易创建一个简单的程序来测试
线程的平均开销。Sleep(1)
使用Stopwatch并得出它收敛到操作系统计时器分辨率(例如15.6毫秒)的结论。但是我发现很难创建一个程序来获得与lock语句相同的结论。主要原因是:

1) 很难确保试图获取锁的线程总是阻塞(或者至少在获取锁之前知道它何时阻塞)

2) 我不知道当线程试图获取锁块时,如何强制上下文切换。当前正在运行的线程阻塞时是否始终存在上下文切换

任何帮助都将不胜感激

假设线程1尝试使用 lock(lockObj)语句,但此对象已被 线程1试图获取其上的锁时,线程2。线 我会封锁的,对吗

现在假设在这个阻塞过程中,有一个上下文切换, 因为还有其他线程和应用程序等待运行。是 直到线程1再次处于运行状态并能够 根据操作系统计时器分辨率获取锁(例如:默认值 Windows 7上的15.6毫秒)

不是直接的,不是。一般来说,线程1将在它被阻塞的等待对象发出信号后立即准备就绪。此时,OS scheduing算法将运行,如果线程1是空闲的,或者其优先级足以允许其包含在可在可用内核上运行的线程集中,则线程1将被设置为在内核上运行。有可能是一个计时器中断了我的同步到达,并将另一个高优先级的“线程3”设置为就绪状态,从而阻止线程1运行,但这与“获取锁取决于操作系统计时器分辨率”的说法相去甚远

如果有一个内核可以自由运行线程1,根据经验,我发现它在Windows系统上的线程2发出信号后运行约7us—几微秒,而不是15.6毫秒或类似的时间

如果线程1必须等到下一个计时器中断后再运行某个信号,那么性能将非常糟糕。无需等待-操作系统已通过来自线程2的信号输入,操作系统决定此时运行哪一组线程。它可能不会立即运行线程1,因为所有内核都已在运行更高优先级的线程;它可能会抢占线程2,因为线程1具有更高的动态优先级;或者,它可能会通过使用其处理器间通信驱动程序向另一个内核发出硬件中断来抢占另一个内核上运行的线程。计时器中断和“量子”东西在您的场景中基本上是不相关的


尽量不要专注于“quantum”概念(这是一个愚蠢的名字,因为“quanta”被认为是不可分割的,并且由于I/O和线程间信令,线程很少以精确的计时器驱动间隔运行),而不要考虑输入为硬件中断和系统调用的状态机,输出是一组在内核上运行的线程。硬件定时器中断只是可以更改运行线程集的输入之一

不,如果是这样的话,线程将非常糟糕。计时器受速率的影响,而不是同步。因此,基本上你是说,当线程因为等待获取锁而阻塞时,它不会被重新安排在下一个操作系统时间片中进行测试,以检查对象上的锁是否已被释放。还有另一种机制使阻塞线程意识到对象上的锁一发生就被释放,并使该线程再次进入运行状态?它只是以相反的方式工作。当同步对象被释放时,操作系统会检查是否有人在等待它。如果是这样,该线程将被解除阻塞,其优先级将提高。通常足够让线程获得一个核心。