我使用线程安全Q在缓冲区内生成一些随机数。在主要的glWidget程序中,我应该DeQ缓冲区内容并更新屏幕。
#ifndef CONCURRENTQUEUE_H
#define CONCURRENTQUEUE_H
#include <QByteArray>
#include <QQueue>
#include <QMutex>
class ConcurrentQueue
{
private:
unsigned short segments[360][100];
public:
ConcurrentQueue();
void InitSegments();
void Enqueue(int i, int j, unsigned short value);
unsigned short Dequeue(int i, int j);
bool isEmpty();
private:
QMutex mutex;
};
#endif // CONCURRENTQUEUE_H
ConcurrentQueue::ConcurrentQueue()
{
InitSegments();
}
void ConcurrentQueue::InitSegments()
{
for(int i = 0; i < 360; i++)
for(int j = 0; j < 100; j++)
{
segments[i][j] = 0;
}
}
void ConcurrentQueue::Enqueue(int i, int j, unsigned short value)
{
mutex.lock();
segments[i][j] = value;
mutex.unlock();
}
unsigned short ConcurrentQueue::Dequeue(int i, int j)
{
unsigned short color = 0;
mutex.lock();
color = segments[i][j];
mutex.unlock();
return color;
}
GenerateBuffers类:
#ifndef GENERATEBUFFERS_H
#define GENERATEBUFFERS_H
#include <QThread>
#include "thread_safe/concurrentqueue.h"
class GenerateBuffers : public QThread
{
public:
GenerateBuffers();
void run();
int rounds;
int segmentIndex;
};
#endif // GENERATEBUFFERS_H
#include "generatebuffers.h"
#include <time.h>
ConcurrentQueue segmentsQueue;
GenerateBuffers::GenerateBuffers()
{
segmentIndex = 1;
run();
}
void GenerateBuffers::run()
{
while(true)
{
int angleIndex = segmentIndex * 23;
for(int i = angleIndex - 23; i < angleIndex; i++)
for(int j = 0; j < 100; j++)
{
unsigned short randNumber = rand() % 255;
segmentsQueue.Enqueue(i, j, randNumber);
}
if(segmentIndex > 16)
{
segmentIndex = 0;
}
else
segmentIndex++;
usleep(150);
}
}
我在generateBuffers .cpp文件中创建了一个ConcurrentQ实例
ConcurrentQueue segmentsQueue;
并在我声明的glWidget头文件中: extern ConcurrentQueue segmentsQueue;
我用这种方式:
ppi->highlight(j, i, segmentsQueue.Dequeue(i, j));
程序在我运行时终止,我不确定我的线程安全实现是否正确。你能告诉我你对这段代码的意见吗。
答案 0 :(得分:1)
尝试用这里的问题猜测我尝试了最简单的一个:索引边界。所以 在你的run()方法中,你试图将segmentIndex绑定到16.想象一下
segmentIndex == 16
现在在循环中
if(segmentIndex > 16) // segmentIndex == 16, (16 > 16) is false
{
segmentIndex = 0;
}
else
{ // we go that way
segmentIndex++; // segmentIndex gets 17
}
现在进行下一次循环运行
// segmentIndex is 17
int angleIndex = segmentIndex * 23; // 17 * 23 == 391
for(int i = angleIndex - 23; i < angleIndex; i++) // i = [368,391)
{
for(int j = 0; j < 100; j++)
{
unsigned short randNumber = rand() % 255;
// unsigned short segments[360][100];
segmentsQueue.Enqueue(i, j, randNumber);
// enqueue doesn't check index, causes crash
}
}
所以你的代码不会起作用。请不要在代码(360,100,23,16)中使用幻数来避免这类问题 顺便说一句,你可以简单地调试问题。
此外,此代码可能不会执行您认为的操作
GenerateBuffers::GenerateBuffers()
{
segmentIndex = 1;
run();
}
在相同的线程上调用 run()。你可能想要start()
而不是