我已经在
中创建了一个非常优秀的Bounded MPMC队列源http://www.1024cores.net/home/lock-free-algorithms/queues/bounded-mpmc-queue
并且测试非常简单:
mpmc_bounded_queue<string> mq(8) ;
for(int idx=0;idx<10;idx++)
{
string s = to_string(idx);
if(mq.enqueue(s))
cout << s << " ok" << endl ;
else
cout << s << " not ok" << endl ;
}
string strx;
if(mq.dequeue(strx))
{
cout << "The dequeue value=" << strx << endl ;
}else{
assert(1 == 2) ;
}
string s = "THE END" ;
if(mq.enqueue(s))
cout << s << " ok" << endl ;
else
cout << s << " not ok" << endl ;
在我学习这段代码之后,我想确定是否可以正确使用此源代码, 假设在唤醒(信号量&gt; 0)之后有一个线程C在等待信号量, 线程C将调用dequeue函数从队列中获取数据!!线程A和线程B. 将调用enqueue函数,插入一个数据后,信号量+ 1,如果是线程A和 线程B排队10次,信号量为10次,然后线程C应该能够出列10次,到目前为止应该是完美的!
但我认为有一件事可能会发生! ...假设线程A和线程B在队列中排队 同时,在Compare-And-Swap之后,线程A应该填充缓冲区[0]和线程B. 应填充缓冲区[1],线程A未完成入队并由操作系统切换, 所以Buffer [0]的sequence_不被修改,线程B完成入队并且增加 信号量,在这个monent,线程A没有完成缓冲区[0],线程B完成缓冲区[1], 线程c因为信号量= 1而被唤醒,因此线程C将出列,并尝试访问 buffer [0],尚未就绪,因此dequeue将返回false,即线程C 应该实现如下:
Right !!
while(1){
sem_wait(sem1) ;
while(1){
if(mq.dequeue(strx))
break ;
}
//doing something about strx
}
=====================================
Wrong !!
while(1){
sem_wait(sem1) ;
mq.dequeue(strx) ;
//doing something about strx
}
=====================================
我的观点是,线程C唤醒意味着有新数据入队,但它可能不在缓冲区[dequeue_pos_]的位置,所以将出队函数放入无限循环中 乐于助人!!!!
我在这个工具中是否正确?我的意思是,应该有机会填充缓冲区[1] 在缓冲区[0]之前,并且线程C唤醒尝试使缓冲区[0]出列失败,请保持出队 在无尽的循环中不会忍受永远等待.....因为当线程A swich in 操作系统,缓冲区[0]填充完毕,线程C将中断循环!!
任何建议,评论都表示赞赏!!!