use*_*362 2 c++ multithreading boost boost-thread
我有一个队列类,其数据存储在向量中:
std::vector<boost::shared_ptr<rxImage> > queue;
Run Code Online (Sandbox Code Playgroud)
有一个线程添加到基于此循环的队列:
while(runRxThread){
this->rxImage();
}
Run Code Online (Sandbox Code Playgroud)
其中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());
Run Code Online (Sandbox Code Playgroud)
这个图像在这个帖子中得到了很好的接收(我已经测试了10,000左右,看起来很好).
runRxThread变量是通过定义线程函数的类中的一些setter函数设置的.
当我在主线程中运行一个进程时,例如:
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();
Run Code Online (Sandbox Code Playgroud)
由clear()引起的段错误.我已经检查过它肯定是这条线而不是对象的内部管道,它绝对是.
它似乎是一个线程安全问题,但我不知道如何解决它,更重要的是,我不知道为什么.我的理解是两个线程可以写入同一个内存,但不能同时写入.当然,通过设置我的runRxThread变量,我确保不会发生这种情况.
我非常想要一个不涉及互斥锁或信号量的解决方案 - 我真的不认为它们对于像这样的问题是必要的.
谢谢!
编辑:runRXThread是volatile并且线程循环现在是:
while(1){
if(runRxThread == 1){
this->rxImage();
}
}
Run Code Online (Sandbox Code Playgroud)
EDIT2:"在共享对象上使用互斥锁"
好吧,这显然是一个线程安全问题,我需要让我的共享变量线程安全.但...
1)rxImage(); 除非有数据发送,否则不会终止
2)段错误发生在rxImage()中;
3)如果我用互斥锁锁定队列,那么程序肯定会在rxImage中挂起,直到有数据,因为互斥锁不会被释放
4)没有数据发送,所以程序将永远挂起.
我的理解不正确吗?
EDIT3:
我已将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;
}
Run Code Online (Sandbox Code Playgroud)
之前的问题显然是在我清理队列时写入了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
Run Code Online (Sandbox Code Playgroud)
可以看出,线程用向量完成,然后图像服务器停止,然后向量被清除.正是按顺序,没有不可预测的行为.但仍然存在一个段落错误.
您的数据竞争在这里:
while(runRxThread){
this->rxImage();
}
Run Code Online (Sandbox Code Playgroud)
您不检查runTxThread()循环的持续时间(更不用说除非runRxThread标记为volatile,否则它甚至可能不会从主存储器中读取,但在寄存器中"假定"未更改.
(注意即使使用volatile,我也只是指出编译器假设一个单线程抽象机器,除非采用显式atomic内存排序模式)
你需要互相排斥.
| 归档时间: |
|
| 查看次数: |
834 次 |
| 最近记录: |