先说明一下 a=a+1这条程序语句的执行步骤:
javascript:;
我在想这种情况:
如果执行到第一步,将a的值读到寄存器R中
执行完这一条后,来了个中断就是 a=a-1 !
等执行完 a=a-1 ,这时候重点来了!
我的CPU会回到 a=a+1 的第二步!
R寄存器里面是不知道 a 已经被改变了,所以他还是按照原先的值 加1!
然后在写回到 a !
这时候就会出现bug了!
这种情况大伙们有考虑过吗? 要怎么避免?
友情提示: 此问题已得到解决,问题已经关闭,关闭后问题禁止继续编辑,回答。
我贴一个完整的无锁队列来终结讨论吧。
这是真正完整的代码。模板参数buflen是队列缓存的长度,T是队列里装的数据类型。
读的一方使用GetData,写的一方使用PutData。限制:只能有一个读者和一个写者。读者不能写,写者不能读。
为了防止队列空的时候去读或者队列满了去写,读写之前都应该用isFull和Len来检查。这两个函数任何地方都可以用。
不管是用于中断和应用程序或者多个线程之间传递数据,都可以随便用。
你看看还有没有什么问题
template<int buflen, typename T>
class TLocklessQueue
{
protected:
T BufData[buflen];
int PutIdx;
int GetIdx;
public:
int MaxSize() {
return buflen;
}
int Len() {
return (PutIdx - GetIdx + buflen) % buflen;
}
bool isFull() {
return Len() == buflen - 1;
}
bool isEmpty() {
return PutIdx == GetIdx;
}
void PutData(const T &aput) {
int aa = PutIdx + 1;
aa %= buflen;
BufData[PutIdx] = aput;
PutIdx = aa;
}
T GetData() {
int aa = GetIdx + 1;
aa %= buflen;
T aget = BufData[GetIdx];
GetIdx = aa;
return aget;
}
};
一周热门 更多>