轮询`pthread_mutex_trylock`是否有意义?

时间:2015-06-16 11:50:43

标签: locking pthreads real-time

考虑运行两个线程的多核系统:线程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没有欠载,它就可以花一些时间做出反应。

1 个答案:

答案 0 :(得分:1)

使用锁定(互斥锁或旋转锁定)不适合低延迟情况 如果您只能共享少量数据,那么它就是最好的,然后您可以在单个原子指令中交换数据。 另一种解决方案是拥有2个数据实例并将指针交换给它。 如果以上情况不适合您,并且您必须回退到互斥锁或旋转锁定,则应该更喜欢自旋锁。
通过旋转锁定,唤醒时间将缩短,因为您没有上下文切换 当线程B持有锁时,线程A必须等待(旋转)。并且您可以将线程B限制为不经常获取锁定 线程B可以尝试获取锁定,经常不会超过一次,如果失败则稍微睡一会。