gpt4 book ai didi

C++清除队列和线程安全

转载 作者:太空狗 更新时间:2023-10-29 23:24:39 24 4
gpt4 key购买 nike

我有一个队列类,它的数据存储在一个 vector 中:

std::vector<boost::shared_ptr<rxImage> > queue;

有一个线程添加到基于此循环的队列中:

while(runRxThread){
this->rxImage();
}

其中 rxImage() 定义为:

zmq::message_t img;
imageSocket->recv(&img);

//addToQueue is a push back:
//queue.push_back( boost::shared_ptr<rxImage> (new rxImage(data, imgSize)) );
localQueue->addToQueue((unsigned char*) img.data());

图像在此线程中接收正常(我测试了 10,000 左右,似乎没问题)。

runRxThread 变量是通过定义线程函数的类中的一些设置函数来设置的。

当我在主线程中运行一个进程时,例如:

startRx(); //start the thread

/*process to stimulate the sending of network data from another program*/

stopRX(); //stop the thread from accessing the queue

queue.clear();

存在由 clear() 引起的段错误。我已经检查过它肯定是这条线而不是对象的内部管道,它确实是。

这似乎是一个线程安全问题,但我不知道如何解决它,更重要的是,我不知道为什么。我的理解是两个线程可以写入同一内​​存,但不能同时写入。当然,通过设置我的 runRxThread 变量,我可以确保不会发生这种情况。

我非常想要一个不涉及互斥锁或信号量的解决方案——我真的不认为它们对于这样的问题是必需的。

谢谢!

编辑:runRXThread 是不稳定的,线程循环现在是:

while(1){
if(runRxThread == 1){
this->rxImage();
}
}

EDIT2:“在共享对象上使用互斥量”

好的,这显然是一个线程安全问题,我需要使我的共享变量线程安全。但是……

1) 接收图像();除非有数据正在发送,否则不会终止

2) 段错误发生在 rxImage();

3) 如果我用互斥锁锁定队列,程序肯定会卡在 rxImage 中直到有数据,因为互斥锁不会被释放

4) 不会有数据发送,所以程序会永远挂起。

我的理解有误吗?

编辑3:

我已将 rxImage() 更改为非阻塞的:

zmq::message_t img;
imageSocket->recv(&img,ZMQ_NOBLOCK);
if((int)img.size() > 0){
cout<<"in the thread conditional"<<endl;
localQueue->addToQueue((unsigned char*) img.data());
cout<<"leaving thread conditional"<<endl;
}

较早的问题显然是在我清除队列时正在写入 localQueue。现在,队列只有在有数据要写入队列时才能写入此函数。我可以保证当我调用 clear() 时,没有数据可写,((int)img.size() > 0) 返回 false 并且线程不访问队列。为什么仍然存在段错误?这肯定证明这个线程不会导致段错误?

这是一个终端输出:

in the thread
pushing back1 of size: 16000000
Added image to queue. queue size: 650
leaving thread conditional

image server stopped
stopping image server
clearing vector
Segmentation fault

可以看出线程完成了vector,然后停止了图像服务器,然后清除了vector。恰好按照该顺序进行,没有意外行为。但是仍然存在段错误。

最佳答案

你的数据竞赛在这里:

while(runRxThread){
this->rxImage();
}

您不会在循环期间检查 runTxThread()(更不用说除非 runRxThread 被标记为 volatile,否则它甚至可能不会从 main 中读取内存,但在寄存器中“假定”未更改。

(注意 即使使用 volatile,竞争仍然存在,我只是指出编译器假设一个单线程抽象机,除非使用显式的 atomic 内存排序模式)

你需要互斥。

关于C++清除队列和线程安全,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/27535530/

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