感谢迈克尔和亚当的评论,我在这里做了一些改变。假设我建立了一个最大长度为 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]。但是每次运行它的结果都可能不同。
有什么想法可以避免这个问题吗?谢谢。