簡體   English   中英

鎖定免費原子循環隊列無法正常工作

[英]Lock free atomic circular queue not working properly

我試圖創建一個無鎖的原子循環隊列,但無法正常工作。

我創建了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上進行了測試。

祝好運!

當我添加一些命令行選項進行編譯時,它可以正常工作。 感謝大家的建議。

我使用以下命令進行編譯。

g ++ -std = c ++ 11 -Full -Wall -pedantic -pthread -latomic main.cpp

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM