1. 如果是一个生产者和一个消费者,则只需对读写index的更新是原子的就可以了,这种情况下只需要两个atomic的变量就搞定
2. 如果是多个生产者,则采用这种方式:
a. 生产者原子的预定一个写的位置
int curWriteIndex = writeIndex;
do{
curWriteIndex = wirteIndex;
}while(cas(writeIndex,curWriteIndex,curWriteIndex + 1))
采用cas原子地获取一个slot,然后写入
b. writeIndex指向的位置不一定可读,因此,需要一个新的变量来指示当前读的位置,mReadIndex, 当a操作完成后,用cas指令更新这个变量
int curReadIndex = mReadIndex;
do{
curReadIndex = mReadIndex;
}while(cas(mReadIndex,curReadIndex,curReadIndex + 1))
c. 如果两个写线程,thread 1 和 thread2, 先后通过a获取到了写入位置,那么他们执行b的顺序一定是与a的顺序一致,因此,如果某个线程执行b失败,那么表面他需要等待,此时最好让出cpu,因为他需要等待
d. 读线程:
int index = readIndex;
do{
index = readIndex;
}while(cas(readindex,index,index + 1))
// 读index 的数据
3. 多个读,一个写:写的index 更新采用atomic的方式即可,读采用cas