0

我正在尝试做一个简单的程序来了解 C++ 中的线程和并发。我创建了一个名为 MyQueue 的模板类,它实现了一个队列和一些变量来处理线程的同步。

该类只有两个用于从队列中获取和放置项目的函数和一个用于关闭队列并避免进一步访问的函数。

该程序编译得很好,但是在调试时出现以下错误:

表达式:deque 迭代器不可取消引用

无论线程在做什么,如果获取或放置项目,都可能发生这种情况。

这是代码:

template <class T> class MyQueue{
queue<T> myqueue;
int N;
bool open;
mutex m,m_open;
condition_variable cv,cv2;

public:
MyQueue(int size){
    N=size;
    open=true;
}

bool isOpen(){ 
    lock_guard<mutex> lg(m_open);
    return open;
}

void close(){
    lock_guard<mutex> lg(m_open);
    open=false;
    cv.notify_all();
    cv2.notify_all();
}

bool get(T &t){
    if(isOpen()==false)return false;
    if(myqueue.size()>0){
        {
            lock_guard<mutex> lg(m);
            t=myqueue.front();
            myqueue.pop();
            cv.notify_one(); 
        }
    }else{
        unique_lock<mutex> ul(m);
        cv2.wait(ul); 
        if(!isOpen()) return false;
        t=myqueue.front();
        myqueue.pop();
        cv.notify_one();
    }
    return true;
}



bool put(T t){
    if(!isOpen())return false;
    if(myqueue.size()<N){
        {
        lock_guard<mutex> lg(m); 
        myqueue.push(t);
        cv2.notify_one(); 
        }
    }else{
        unique_lock<mutex> ul(m);
        cv.wait(ul);
        if(!isOpen())return false;
        myqueue.push(t);
        cv2.notify_one();
    }
    return true;
}

};
4

1 回答 1

0

我通过在 get 和 put 函数中从 wait 更改为 wait_for 解决了这个问题。例如在获取:

if(!cv.wait_for(lock, std::chrono::milliseconds(2100), [this] { return !myQueue.empty();})) return false;

以这种方式,线程只等待设定的时间,调用 myQueue.empty() 不需要适当的锁(如答案中所建议的那样)。

于 2013-04-16T13:10:06.137 回答