C++ 是否有任何对象可以作为FIFO与事件一起用于弹出数据?

C++ 是否有任何对象可以作为FIFO与事件一起用于弹出数据?,c++,multithreading,stl,queue,C++,Multithreading,Stl,Queue,我需要有一个FIFO对象,当它有一个元素时,它会生成一个事件或进行回调以通知元素可用。就我所见,std:queue不支持这个 在我的例子中,我有两个线程,一个线程生成数据,另一个线程需要使用它们 第一个线程生成数据的速度不是固定的,因此我需要一个缓冲区来存储数据,以便另一个线程能够以相对恒定的方式读取和处理数据 我知道如何实现writer,但在读卡器端,如果我轮询队列,那么我将失去一些处理能力来检查队列状态,我想知道是否有更好的方法来实现这一点 编辑1 这并不是关于队列的线程安全,而是std::

我需要有一个FIFO对象,当它有一个元素时,它会生成一个事件或进行回调以通知元素可用。就我所见,std:queue不支持这个

在我的例子中,我有两个线程,一个线程生成数据,另一个线程需要使用它们

第一个线程生成数据的速度不是固定的,因此我需要一个缓冲区来存储数据,以便另一个线程能够以相对恒定的方式读取和处理数据

我知道如何实现writer,但在读卡器端,如果我轮询队列,那么我将失去一些处理能力来检查队列状态,我想知道是否有更好的方法来实现这一点

编辑1
这并不是关于队列的线程安全,而是std::queue是基于轮询工作的,但我需要一些基于事件的东西。STD::队列不是基于事件的,在新数据可用时不会调用。

> P>如果我理解了你的问题,你可以很好地使用C++ <代码> STD::条件变量在线程之间通知关于队列中的可用性,然后调用回调。p> 代码看起来像这样。这里,主线程充当生成器线程,接收线程充当使用者线程

std::condition_variable Cv_;
std::mutex Mutex_;
std::queue<int> qVal;

void callback() {
    cout << "Callback Called with queue Value =>" << qVal.front() << endl;
    qVal.pop();
}
void ReceiveThread() {

    while (true) {
        std::unique_lock<mutex> Lock(Mutex_);
        Cv_.wait(Lock);
        callback();
    }
}

int main() {
    thread thrd(ReceiveThread);
    int pushVal = 1;
    while (1) {
        this_thread::sleep_for(std::chrono::seconds(1));
        qVal.push(pushVal);
        cout << "Signalling for callback with value = " << pushVal<< endl;
        pushVal++;
        Cv_.notify_all();
    }
}
std::条件变量Cv;
std::mutex mutex;
std::队列qVal;
void callback(){
coutstd::queue::push()
函数中没有任何占位符,因此我们可以简单地将
回调函数
引用放入其中,以便在
队列
中成功插入元素后,
回调函数
将被调用

std::queue::push(data)
{
    //add data to internal container

    //placeholder section--------
    //invoke call_back function or event.
    //placeholder section--------
}
因此,在没有此类占位符的情况下,我们可以尝试使用RAII自动调用
回调函数
或某些事件

假设我们将实际数据包装在一个
struct
中,这将帮助我们进行通知。然后,我们将被要求通过这个
struct
的对象间接访问实际数据

struct data_notifier
{
    //the true data.
    int actual_data;

    data_notifier(int data) : actual_data(data)
    {
        //signal event queue_full       
        //or
        //call a call_back function.
    }
}

int actual_data = 90;
std::queue<data_notifier*> q;
q.push(new data_notifier(actual_data));

你在寻找合适的STL容器或模式吗?@RawN任何解决方案,显然,如果STL已经有了容器,它会更好,否则如何实现一个更好。有queue,然后是deque。如果你正在考虑从现有类模板继承-不要。@RawN std::queue和std::deque都是轮询基础,但是我需要一个事件库。我需要一个通知读者新数据可用的东西,当没有可用数据时,读者正在等待一个事件或等待一个互斥锁等等,这样读者就不会有轮询队列以查找是否有数据的开销。我怀疑是否存在事件库STL容器。YOU可能在寻找一个设计模式或一个变体。我认为C++中没有一个“盒外事件”。谢谢,因为STD::队列不是线程安全的,这个代码是否正常工作,因为我看不到任何STD::队列在任何时候只被一个线程使用的保护。我错了吗?@曼:不,先生,你没有错。你需要保护。在使用“Mutex\ux”将内容放入队列之前,主线程。我没有这样做,因为我的代码主要是为了展示如何实现您正在尝试的操作。谢谢,非常感谢。我可以使用相同的Mutex(Mutex\ux)吗为了保护对std:queue的访问,或者我需要一个新的互斥体?@mans您可以对与
std::lock\u guard lgm(互斥体)
//event_full is a manual event which needs to be signalled and non-signalled manually.

void Writer()
{
    while(1)
    {
        //[1] wait for mutex_queue
        //[2] myqueue.push(data);
        //[3] data is now persisted so signal event_full
        //[4] release mutex_queue
    }
}

void Reader()
{   
    while(1) 
    {
        //[1] wait for event_full (so no polling)

        //[2] wait for mutex_queue

        //[3] --- access queue ---
        if(myqueue.size() != 0)
        {
            //process myqueue.front()
            //myqueue.pop();
        }
        if(myqueue.size() == 0)
        {
            //reset event_full      
            //so as long as queue has data, Reader can process it else needs to wait. 
        }
        //[3] --- access queue ---

        //[4] release mutex_queue   
    }
}