加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 百科 > 正文

c – std :: thread在使用参数创建时抛出访问冲突异常?

发布时间:2020-12-16 06:52:23 所属栏目:百科 来源:网络整理
导读:我正在使用VS2015并在使用std :: thread时遇到一个非常奇怪的问题. void Klass::myfunc(int a,int b) { std::cout a ' ' b std::endl; }// ...auto t = std::thread(Klass::myfunc,this,100,200); - runtime error after called// ...t.join(); 它在调试模式
我正在使用VS2015并在使用std :: thread时遇到一个非常奇怪的问题.

void Klass::myfunc(int a,int b) { std::cout << a << ' ' << b << std::endl; }
// ...
auto t = std::thread(&Klass::myfunc,this,100,200); <- runtime error after called
// ...
t.join();

它在调试模式下运行良好,但在转向发布模式时会抛出“访问冲突异常”.

更重要的是,如果我尝试将“myfunc”修改为:

void Klass::myfunc() { std::cout << "foo" << std::endl; }
// ...
auto t = std::thread(&Klass::myfunc,this); // everything goes well
// ...
t.join();

它再次运作良好.

我保证“& Klass :: myfunc”和“this”指针不是NULL.当调用ctor时,在几行之后有一个“连接”.

我想这可能是某种“未定义的行为”,但我不知道究竟是什么.

调用堆栈是这样的:

000000c83a4ffd40()  Unknown
>   distributed_word_embedding.exe!std::_LaunchPad<std::unique_ptr<std::tuple<void (__cdecl multiverso::Communicator::*)(void) __ptr64,multiverso::Communicator * __ptr64>,std::default_delete<std::tuple<void (__cdecl multiverso::Communicator::*)(void) __ptr64,multiverso::Communicator * __ptr64> > > >::_Run(std::_LaunchPad<std::unique_ptr<std::tuple<void (__cdecl multiverso::Communicator::*)(void),multiverso::Communicator *>,std::default_delete<std::tuple<void (__cdecl multiverso::Communicator::*)(void),multiverso::Communicator *> > > > * _Ln) Line 247    C++
    distributed_word_embedding.exe!std::_Pad::_Call_func(void * _Data) Line 210 C++
    ucrtbase.dll!00007ffabdc7be1d() Unknown
    kernel32.dll!00007ffabfae8102() Unknown
    ntdll.dll!00007ffac26bc5b4()    Unknown

解决方法

你应该总是确保你加入(或可能分离)一个线程,否则主要特别是使用对象的线程(在这种情况下这个)会(有时)导致问题.

//... details omitted...

int main()
{
  auto t = std::thread(&Klass::myfunc,this);
  t.join();  //<----- NOTE THIS
}

安东尼威廉的线程blog详细介绍了这一点.举个例子与你的第二个非常类似:

void my_thread_func()
{
    std::cout<<"hello"<<std::endl;
}

int main()
{
    std::thread t(my_thread_func);
}

他说

If you compile and run this little application,what happens? Does it
print hello like we wanted? Well,actually there’s no telling. It
might do or it might not. I ran this simple application several times
on my machine,and the output was unreliable: sometimes it output
“hello”,with a newline; sometimes it output “hello” without a
newline,and sometimes it didn’t output anything. What’s up with that?
Surely a simple app like this ought to behave predictably?

然后他介绍了如上所述使用join的想法,并说,

The problem is we’re not waiting for our thread to finish. When the execution reaches the end of main() the program is terminated,whatever the other threads are doing.

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读