我试图创建一个无锁的原子循环队列,但无法正常工作。

我创建了2个线程。一种用于推送到队列中,另一种用于从队列中弹出。但;

问题:
-当推线程运行时,弹出线程无法运行。弹出线程在推送线程完全运行之后运行,反之亦然。

我对C ++不太了解。因此,请您可以编辑我的代码以使其起作用吗?

我正在使用GCC 4.8.1

提前致谢。

码:

#include <cstdlib>
#include <iostream>
#include <atomic>
#include <cstddef>
#include <thread>
#include <stdio.h>
#include <unistd.h>

#define capacity 1000



std::atomic<int> _head;
std::atomic<int> _tail;

int array[capacity];

int increment(int size)
{
    return (size+1)%capacity;
}

bool push(int *item)
{
    printf("Inside push\n");
    const int current_tail= _tail.load(std::memory_order_relaxed);
    const int next_tail=increment(current_tail);

    if(next_tail != _head.load(std::memory_order_acquire))
    {
         array[current_tail]=*item;
         _tail.store(next_tail,std::memory_order_release);

         return true;
    }

         return false; //Queue is Full
}

bool pop(int *item)
{
      printf("Inside pop\n");
      const int current_head=_head.load(std::memory_order_relaxed);

      if(current_head==_tail.load(std::memory_order_acquire))
      {
          return false;//empty queue
      }

      *item=array[current_head];
      _head.store(increment(current_head),std::memory_order_release);

      return true;
}

bool isEmpty()
{
    return(_head.load()==_tail.load());
}

bool isFull()
{
    const int next_tail=increment(_tail);

    return (next_tail==_head.load());
}

bool isLockfree()
{
    return (_tail.is_lock_free() && _head.is_lock_free());
}

void *threadfunction_push()
{
    int item,i;
    bool flag;
    item=0;

    for(i=0;i<10000;i++)
    {
        while(isFull())
        std::this_thread::yield();

        ++item;
        push(&item);
        printf("pushed %d into queue\n",item);
        //usleep(100);

     }

}

void *threadfunction_pop()
{
    int item,i;

    item=0;
    for(i=0;i<10000;i++)
    {
       while(isEmpty())
             std::this_thread::yield();

       pop(&item);
       printf("popped %d from queue\n",item);


    }

     i=isLockfree();
     if(i)
        printf("Queue is lock Free");
}


int main(int argc, char** argv)
{


    std::thread thread_push(threadfunction_push);
    std::thread thread_pop(threadfunction_pop);

    thread_push.join();
    thread_pop.join();

     return 0;
}

最佳答案

您需要了解的第一件事是单核单线程处理器上的多线程。如果运行以上代码的处理器是单核单线程处理器,则不会有并行运行的线程。这种处理器上的多线程有点像多进程概念。一次仅运行一个线程,并且在一定时间段后,当第一个线程使用了其时间片时,操作系统将调度它进入睡眠状态,而另一个线程启动并开始运行。这就是为什么看到“ Pop线程在push线程完全运行之后运行,反之亦然”的原因。

实际上,@ MikeMB指出了根本原因,其原因是运行循环太短。如果将阵列容量更改为100,000,并将pop线程和push线程的循环计数器i增加到1000或更多,您将看到pop和push将交替运行。这已在我的带有gcc4.9.2的vmware CentOS 6.4上进行了测试。

祝好运!

关于c++ - 锁定免费原子循环队列无法正常工作,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/31310437/

10-11 22:46
查看更多