对于 pthreads,标准方法是使用互斥体并使用条件变量在一个线程中等待,直到被另一个线程唤醒。
伪代码,其中 writer 将短暂阻塞,但不会在不确定的时间内阻塞,并且通过丢弃未读数据来处理缓冲区溢出:
作家写道:
acquire new data to write
lock mutex
get current writing position in buffer
compare to current reading position and check for overflow
in case of overflow, update reading position (oldest data lost)
write new data to buffer
update writing position
do wakeup on condition variable
unlock mutex
读者阅读:
lock mutex
loop:
get current reading position in buffer
compare to current writing position in buffer
if there's new data, break loop
wait (possibly with timeout) on condition variable
goto loop:
copy data from buffer
update reading position
unlock mutex
process copied data
显然,在上面,writer 可能会短暂地阻塞 mutex,但因为 reader 只会短暂地持有 mutex(这假设缓冲区中的数据相当短),这可能不是问题。
关于理解上述代码的重要细节:条件变量和互斥锁成对工作。等待条件变量将解锁互斥锁,一旦唤醒,只有在它可以重新锁定互斥锁后才会继续。因此,在作者解锁互斥锁之前,阅读器实际上不会继续。
当条件变量等待返回时再次检查缓冲区位置很重要,不要盲目地相信唤醒是由写入器完成的,它只是向它添加了更多数据。