0

感谢迈克尔和亚当的评论,我在这里做了一些改变。假设我建立了一个最大长度为 N 的特殊链接队列。

class QueueItem
{
  int id; //object identity
  double data; //object priority 
}

class MyQueue
{
  private:
    list<QueueItem> rec;
    std::mutex mymutex;
  public:
    LinkArray(){};
    ~LinkArray(){};
    int insert(int id, double d)
    {
      std::lock_guard<std::mutex> guard(mymutex);
      list<QueueItem>::iterator iter=rec.begin();
      QueueItem temp;
      temp.id = id;
      temp.data = d;
      int count=0;
      for (iter;iter!=rec.end();iter++)
      {
        if (iter->data<d)
        {
          rec.insert(iter,temp);
          return count;
        }
        count++;
      }
      rec.push_back(temp);
      return count;
    }
    void pop(void)
    {
      std::lock_guard<std::mutex> guard(mymutex);
      rec.pop_back();
    }
    int getLength(void)
    {
      return rec.size();
    }

};

规则是:队列中的所有项目总是具有最高优先级并且它们被排序。例如对于 N=4,队列中的优先级为 (100,99,98,97)。当优先级 101 入队时,队列变为 (101,100,99,98)。如果 1 入队,则队列不会改变。

现在,如果我<thread>在 C++11 中使用来计算不同线程中不同对象的优先级,然后将它们排入队列,我该如何避免竞争条件?

我的代码是这样的:

 ....
 int N = 4; //queue length
 int pnum=4;//thread number
 MyQueue* queue = new MyQueue(8);
 vector<thread> threads;
 std::mutex mymux;
 int totalItem = 16;
 int itemIds[] = {0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15};
 double itemPriority[] = {9,10,3,11,2,12,5,6,7,8,1,15,14,4,13,16};
 int itemperthread = totalItem/pnum;
 for (int p=0; p<pnum;p++)
 {
    threads.push_back(thread([&](int p, MyQueue* queue ){
       for (int i=p*itemperthread; i<(p+1)*itemperthread; i++)
       { 
         int id = itemIds[i];
         int priority = itemPriority[i];
       }
       mymux.lock();
       queue->insert(id,priority); //enqueue
       if (queue->getLength()>N)
         queue->pop();
       mymux.unlock();
    },p, queue));
 }
 for (auto& thread : threads){
   thread.join();
 }

我尝试使用互斥锁来锁定队列(甚至在 Queue 类中定义互斥锁并在 Queue::insert 方法中使用它)。但是每次我运行这个,队列的结果都是不同的。我很确定优先级的计算是正确的。

运行这部分程序后的预期队列将是 [16,15,14,13]。但是每次运行它的结果都可能不同。

有什么想法可以避免这个问题吗?谢谢。

4

0 回答 0