带信号量的有界MPMC队列

时间:2013-09-27 02:17:30

标签: c++ c multithreading queue semaphore

我已经在

中创建了一个非常优秀的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将中断循环!!

任何建议,评论都表示赞赏!!!

0 个答案:

没有答案