Linux pthread互斥和内核调度程序

对于我的一位朋友,我们不同意在用户空间级别(在pthread库中)处理同步的方式.

一个.我认为在pthread_mutex_lock期间,线程会主动等待.这意味着linux调度程序上升了这个线程,让它执行他的代码,它应该如下所示:

while (mutex_resource->locked);

然后,调度另一个线程,可能释放锁定的字段等.
所以这意味着调度程序在切换到下一个调度程序之前等待线程完成其调度时间,无论线程在做什么.

湾我的朋友认为等待线程以某种方式告诉内核“嘿,我睡着了,根本不要等我”.
在这种情况下,内核会立即调度下一个线程,而不必等待当前线程完成其调度时间,意识到此线程正在休眠.

从我在pthread的代码中看到的,似乎有循环处理锁.但也许我错过了什么.

在嵌入式系统中,防止内核等待是有意义的.所以他可能是对的(但我希望他不会:D).

谢谢!

解决方法:

a. I think that during a pthread_mutex_lock, the thread actively waits.

是的,glibc的NPTL pthread_mutex_lock有活动等待(旋转),
但纺纱仅在非常短的时间内使用,仅适用于某些类型的互斥体.在此数量之后,通过使用WAIT参数调用linux syscall futex,pthread_mutex_lock将进入休眠状态.

只有类型为PTHREAD_MUTEX_ADAPTIVE_NP的互斥锁才会旋转,默认值为PTHREAD_MUTEX_TIMED_NP(正常互斥锁)而不会旋转. Check MAX_ADAPTIVE_COUNT in __pthread_mutex_lock sources).

如果要进行无限旋转(主动等待),请使用带有pthread_spinlock_t-types锁的pthread_spin_lock函数.

我会考虑您的其余问题,就好像您正在使用pthread_spin_lock:

Then, another thread is scheduled which potentially free the locked field, etc. So this means that the scheduler waits for the thread to complete its schedule time before switching to the next one, no matter what the thread is doing.

是的,如果存在CPU内核争用,那么具有活动旋转的线程可能阻止其他线程执行,即使另一个线程是解锁线程所需的互斥锁(自旋锁)的线程.

但是如果没有争用(没有线程超额订阅),并且线程被安排在不同的核心上(通过巧合,或通过手动设置cpu亲和力与sched_setaffinity或pthread_setaffinity_np),旋转将使您能够更快地进行,然后使用基于操作系统的futex .

b. My friend thinks that the waiting thread somehow tells the kernel “Hey, I’m asleep, don’t wait for me at all”. In this case, the kernel would schedule the next thread right away, without waiting for the current thread to complete…

是的,他是对的.

futex是现代的说OS的方式,这个线程在内存中等待某些值(用于打开一些互斥锁);在当前的实现中,futex也让我们的线程进入睡眠状态.如果内核知道何时唤醒此线程,则不需要将其唤醒以进行旋转.怎么知道?锁定所有者在执行pthread_mutex_unlock时会检查,是否还有其他线程在这个互斥锁上休眠.如果有,锁定所有者将使用FUTEX_WAKE调用futex,告诉操作系统唤醒一些线程,在此互斥锁上注册为睡眠者.

如果线程在OS中将自己注册为服务员,则无需旋转.

上一篇:P3 Day03 MyBatisPlus


下一篇:Linux中的热感知调度程序