对象地址突然更改


class test
{
void thread1()
{
int i = 0;
while(true){
for(unsigned int k = 0;k < mLD.size(); k++ )
{
mLD[k] = i++;
}
}
}
void thread2()
{
std::cout << "thread2 address  : " << &mLD << "n";
C();
}
void B()
{
std::cout << "B address  : " << &mLD << "n";
for(unsigned int k = 0;k < mLD.size(); k++ )
{
if(mLD[k]<=25)
{
}
}
}
void C()
{
B();
std::cout << "C address  : " << &mLD << "n";
double distance = mLD[0];  //  <---- segmetation fault
}
std::array<double, 360> mLD;
};

cout结果--->

线程2地址:0x7e807660

B地址:0x7e807660

C地址:0x1010160(有时为0x7e807660(

为什么mLD的地址更改了。。。。?

即使我将std::array更改为std::array<std::atomic<double>360>,结果也是一样的。

最有可能的是,您引用的对象在调用C时被销毁,这表明存在同步问题。您需要延长线程引用的对象的生存期,直到线程执行完它们的例程。为了实现这一点,你可以拥有这样的东西;

#include <thread>
#include <array>
#include <iostream>
struct foo{
void callback1(){
for(auto & elem: storage){
elem += 5;
}
}
void callback2(){
for(const auto & elem: storage){
std::cout << elem << std::endl;
}
}
std::array<double, 300> storage;
};
int main(void){
foo f;
std::thread t1 {[&f](){f.callback1();}};
std::thread t2 {[&f](){f.callback2();}};
// wait until both threads are done executing their routines
t1.join();
t2.join();
return 0;
}

foo,f的实例位于main((函数的作用域中,因此它的"生存期"是通过从它定义的行到main作用域的末尾来定义的。通过连接两个线程,我们阻止main继续进行,直到两个线程都执行完它们的回调函数,因此f的生存期延长,直到回调完成。

第二个问题是,代码需要同步原语,因为存储变量在两个独立的执行路径之间共享。具有适当同步的最终代码可以是这样的;

#include <thread>
#include <array>
#include <iostream>
#include <mutex>
struct foo{
void callback1(){
// RAII style lock, which invokes .lock() upon construction, and .unlock() upon destruction 
// automatically.
std::unique_lock<std::mutex> lock(mtx);
for(auto & elem: storage){
elem += 5;
}
}
void callback2(){
std::unique_lock<std::mutex> lock(mtx);
for(const auto & elem: storage){
std::cout << elem << std::endl;
}
}
std::array<double, 300> storage;
// non-reentrant mutex
mutable std::mutex mtx;
};
int main(void){
foo f;
std::thread t1 {[&f](){f.callback1();}};
std::thread t2 {[&f](){f.callback2();}};
// wait until both threads are done executing their routines
t1.join();
t2.join();
return 0;
}

最新更新