gpt4 book ai didi

c++ - 线程安全实现给出段错误

转载 作者:太空宇宙 更新时间:2023-11-04 11:53:50 24 4
gpt4 key购买 nike

我正在使用线程安全 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;
}

生成缓冲区类:

#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));

程序在我运行时终止,我不确定我的线程安全实现是否正确。你能告诉我你对代码的看法吗?

最佳答案

为了猜测这里的问题,我尝试了最简单的一个:索引边界。所以在您的 run() 方法中,您试图将 segmentIndex 绑定(bind)到 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
}
}

因此您的代码将无法正常工作。请不要在您的代码中使用魔数(Magic Number)(360、100、23、16)以避免此类问题。
顺便说一下,您可以简单地调试问题。

另外,这段代码可能并不像你想象的那样

GenerateBuffers::GenerateBuffers()
{
segmentIndex = 1;
run();
}

run() 在相同 线程上被调用。你可能想要 start() 而不是

关于c++ - 线程安全实现给出段错误,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/17019377/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com