与我的一个朋友,我们不同意在用户空间级别(在pthread库中)如何处理同步。
一个。我认为在pthread_mutex_lock期间,线程会积极等待。意思是linux调度程序上升了这个线程,让它执行他的代码,看起来应该像这样:
while (mutex_resource->locked);
然后,调度另一个线程,该线程可能会释放该locked
字段,依此类推。因此,这意味着调度程序将等待该线程完成其调度时间,然后再切换到下一个线程,而不管线程在做什么。
b。我的朋友认为等待线程以某种方式告诉内核“嘿,我睡着了,根本不等我”。在这种情况下,内核将立即调度下一个线程,而无需等待当前线程完成其调度时间,因为内核知道此线程正在休眠。
从我在pthread代码中看到的来看,似乎存在处理该锁的循环。但是也许我错过了一些东西。
在嵌入式系统中,防止内核等待可能是有意义的。所以他可能是正确的(但我希望他不是:D)。
谢谢!
一个。我认为在期间
pthread_mutex_lock
,线程会积极等待。
是的,glibc的NPTLpthread_mutex_lock
具有主动等待(旋转),但是旋转仅在很短的时间内使用,并且仅用于某些类型的互斥体。超出此数量后,pthread_mutex_lock
将通过使用WAIT参数调用linux syscallfutex
进入睡眠状态。
只有类型为PTHREAD_MUTEX_ADAPTIVE_NP的互斥体才会旋转,并且默认值为PTHREAD_MUTEX_TIMED_NP
(普通互斥体)而不旋转。签MAX_ADAPTIVE_COUNT
入__pthread_mutex_lock
来源)。
如果要进行无限旋转(主动等待),请使用-types锁pthread_spin_lock
功能pthread_spinlock_t
。
我将把您剩下的问题当作您正在使用的那样pthread_spin_lock
:
然后,调度另一个线程,该线程可能释放锁定的字段,依此类推。因此,这意味着调度程序将等待该线程完成其调度时间,然后再切换到下一个线程,而不管线程在做什么。
是的,如果CPU内核存在争用,即使处于活动状态的线程将解锁该线程所需的互斥锁(自旋锁),该活动旋转的线程也可能阻止其他线程执行。
但是,如果没有争用(没有线程超额预订),并且线程被安排在不同的内核上(通过巧合,或者通过手动设置cpu与sched_setaffinity
或的亲和力pthread_setaffinity_np
),那么旋转将使您可以更快地进行处理,然后使用基于OS的futex。
b。我的朋友认为等待线程以某种方式告诉内核“嘿,我睡着了,根本不等我”。在这种情况下,内核将立即调度下一个线程,而无需等待当前线程完成...
是的,他是对的。
futex
用现代的方式来表示操作系统此线程正在等待内存中的某个值(用于打开mutex
);在当前的实现中futex
,我们的线程也进入睡眠状态。如果内核知道何时唤醒此线程,则无需唤醒它即可进行旋转。怎么知道的?锁所有者在执行时pthread_mutex_unlock
,将检查是否有其他线程在此互斥体上休眠。如果有任何,锁的拥有者将调用futex
同FUTEX_WAKE
,告诉OS唤醒一些线索,注册为这个互斥卧铺。
如果线程在OS中将自己注册为服务员,则无需旋转。
本文收集自互联网,转载请注明来源。
如有侵权,请联系[email protected] 删除。
我来说两句