考虑运行两个线程的多核系统:线程A和线程B,它们共享一些数据。线程A需要尽可能快地完成它的工作,所以我们希望它尽可能地清醒。
使用自旋锁( pthread 或在原子基元之上实现)将被丢弃,因为我们在等待获取锁时更喜欢线程B休眠。
以下方式混合忙等待(自旋锁定)和“困倦等待”是否是可接受的解决方案?:
pthread_mutex_t mutex; // Already initialized somewhere
SharedData data; // Structure for interthread communication
// Thread A (high throughput needed => spin)
while (appRunning) {
while (pthread_mutex_trylock(&mutex) != 0) { } // Controversial point
// Read/write to data
pthread_mutex_unlock(&mutex);
}
// Thread B (should sleep during wait => standard locking)
while (appRunning) {
pthread_mutex_lock(&mutex);
// Read/write to data
pthread_mutex_unlock(&mutex);
}
PS:我试图通用,但如果重要的话,实际情况是线程A根据线程B通过共享数据请求的内容填充低延迟音频缓冲区并写入一些结果。线程B对用户输入作出反应,只要线程A没有欠载,它就可以花一些时间做出反应。
答案 0 :(得分:1)
使用锁定(互斥锁或旋转锁定)不适合低延迟情况
如果您只能共享少量数据,那么它就是最好的,然后您可以在单个原子指令中交换数据。
另一种解决方案是拥有2个数据实例并将指针交换给它。
如果以上情况不适合您,并且您必须回退到互斥锁或旋转锁定,则应该更喜欢自旋锁。
通过旋转锁定,唤醒时间将缩短,因为您没有上下文切换
当线程B持有锁时,线程A必须等待(旋转)。并且您可以将线程B限制为不经常获取锁定
线程B可以尝试获取锁定,经常不会超过一次,如果失败则稍微睡一会。