Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/multithreading/4.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
Multithreading 为什么每次与互斥体同步时都会得到线程上下文切换?_Multithreading_Mutex_Thread Synchronization_Context Switch - Fatal编程技术网

Multithreading 为什么每次与互斥体同步时都会得到线程上下文切换?

Multithreading 为什么每次与互斥体同步时都会得到线程上下文切换?,multithreading,mutex,thread-synchronization,context-switch,Multithreading,Mutex,Thread Synchronization,Context Switch,我有多个线程在紧循环中更新单个数组。(双核处理器上有10个线程,大约每秒更新100000次)。每次在互斥对象(WaitForSingleObject/ReleaseMutex)的保护下更新阵列时。我注意到,没有线程会对数组进行两次连续更新,这意味着必须有某种与同步相关的收益。这意味着每秒大约有100000次上下文切换,这似乎是次优的。为什么会发生这种情况 这里的问题是,所有等待的线程都有一个顺序 WaitForSingleObject中阻塞的每个线程进入一个队列,然后由调度程序挂起,这样就不会再

我有多个线程在紧循环中更新单个数组。(双核处理器上有10个线程,大约每秒更新100000次)。每次在互斥对象(WaitForSingleObject/ReleaseMutex)的保护下更新阵列时。我注意到,没有线程会对数组进行两次连续更新,这意味着必须有某种与同步相关的收益。这意味着每秒大约有100000次上下文切换,这似乎是次优的。为什么会发生这种情况

这里的问题是,所有等待的线程都有一个顺序

WaitForSingleObject中阻塞的每个线程进入一个队列,然后由调度程序挂起,这样就不会再占用执行时间。释放互斥体后,调度程序将恢复一个等待的线程。目前还不清楚从队列中唤醒线程的确切顺序,但在许多情况下,这将是一种简单的先进先出方法


现在发生的情况是,如果同一线程释放互斥体,然后在同一互斥体上执行另一个WaitForSingleObject,他将被重新插入队列,并且如果已经有其他线程在等待,他将不太可能被插入队列前面。这是有道理的,因为允许他跳到队列前面可能会导致其他线程饿死。因此,调度程序可能只是挂起他,然后唤醒队列前面的线程。

我想这是因为多处理器


当第一个线程(运行在第一个处理器上)释放互斥时,第二个线程(运行在第二个处理器上)获得互斥,然后当第一个线程尝试获取互斥时,它无法获得互斥。当第二个线程最终释放互斥锁时,第三个线程(在第一个处理器上)将接收互斥锁。

每个线程的优先级是多少?所有线程的优先级都相同。您如何准确调用
WaitForSingleObject
?特别是,你给它什么暂停时间?如果您使用的是INFINITE,我想这将是我使用INFINITE时的预期行为,但我希望每个线程都会使用完它的时间片(在上下文切换之前多次连续更新),这可能是因为多处理器。当第一个线程(运行在第一个处理器上)释放互斥时,第二个线程(运行在第二个处理器上)获得互斥,然后当第一个线程尝试获取互斥时,它无法获得互斥。当第二个线程最终释放互斥体时,第三个线程(在第一个处理器上)将接收互斥体。您是说每次调用ReleaseMutex时调度程序都会运行吗?不一定。但是,每当调度程序调用
WaitForSingleObject
时,您的线程都必须等待调度程序,并且已经有其他线程在等待相同的互斥体。但是,如果互斥体被另一个线程占用,它只需等待调度程序?这取决于实现。在这种情况下,
WaitForSingleObject
触发的系统调用可以提前返回,但这只是一种优化。但是,如果他提前返回,如果有线程等待,则会导致不公平的调度。第一种情况是效率问题,第二种情况是正确性问题。在现代操作系统上,等待的线程根本不应该被调度。调度程序知道,只要互斥锁被锁定,线程就无法继续,因此他不会为其分配任何时间片。试试自己:在TythyType上旋转::在C++中,屈服()将总是浪费一个完整的CPU内核,而在一个互斥或WAITE()上调用一个条件变量的锁()将不会。@ CAMICSASMS:我已经读了你的答案,这就是我所期望的,但不确定。所有的
WaitForSingleObject
都在一个队列中,因此在调用
ReleaseMutex
后,一个线程将位于所有其他线程之后。这也是为什么我问@FunkyOordvork他是否有权访问单核机器的原因。@Comics回答你是对的,一个等待的线程没有运行,所以每次发布时调度程序都必须运行,这看起来是次优的,但这可能只是因为我缺乏知识!当只使用一个内核时,检查行为是否相同确实很有趣。对的几次调用就可以做到这一点。@FunkyOordvork一位操作系统工程师可能会说,您使用互斥锁的情况不是最佳的;)如果必须立即重新锁定互斥锁,为什么要首先释放互斥锁?您可以通过以不再发生这种情况的方式重新构造代码来绕过整个问题。