是否可以阻止等待信号量而不使用数据?

时间:2017-07-18 14:33:17

标签: multithreading qt c++11 semaphore producer-consumer

我正在研究的软件是带有滑动窗口的数据分析器。我有2个线程,一个生产者和一个消费者,它们使用循环缓冲区。

只有当缓冲区中的第一个元素足够大时,消费者才必须处理数据,因此缓冲区中至少有X个元素。但是在处理之后,由于移动窗口,只能删除X / 4数据。

我的解决方案效果很好,除了我在快速(忙于等待检查)或有效(睡眠一段时间)之间进行权衡。问题是睡眠时间根据负载,线程调度和细化复杂性而变化,因此我可能会降低性能。

有没有办法轮询信号量以检查是否至少有X个元素,否则阻塞线程,但在处理完成后只获取X / 4? tryAcquire选项不起作用,因为当它唤醒时,线程会消耗所有数据,而不是一半。

我考虑过在第二个缓冲区中复制元素,但实际上有7个大数据循环缓冲区,因此我想避免数据重复,甚至数据移动。

//common structs
QSemaphore written;
QSemaphore free;
int writtenIndex = 0;
int readIndex = 0;
myCircularBuffer buf;
bool scan = true;


//producer
void produceData(data d)
{
    while ( free.tryAcquire(1, 1000) == false && scan == true)
    {
        //avoid deadlock!
        //once per second give up waiting and check if closing
    }

    if (scan == false) return;

    buf.at(writtenIndex) = d;
    writtenIndex = (writtenIndex+1) % bufferSize;
    written.release();
}


//consumer
void consumeData()
{
while(1)
{
    //here goes the problem: usleep (slow), sched_yield (B.F.O.W.) or what?  
    if (buf.at(writtenIndex).age - buf.at(readIndex).age < X)
    {
        //usleep(100); ? how much time?
        //sched_yield(); ?
        //tryAcquire not an option!
        continue;
    }

    processTheData();

    written.acquire(X/4);
    readIndex = (readIndex + X/4) % bufferSize; 
    free.release(X/4);
}

0 个答案:

没有答案