2016-08-24 4 views
3

私はVS2015を使用しており、std :: threadを使用すると非常に奇妙な問題が発生します。std :: thread throws引数を使用して作成されたアクセス違反例外?

デバッグモードでは正常に機能しますが、リリースモードに切り替えると「アクセス違反例外」がスローされます。

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

それが再びうまく機能:私はこれに "myfunc関数" を変更しようとする場合には、より多くの何

"& Klass :: myfunc"と "this"ポインタがNULLでないことが保証されています。そしてctorが呼び出されると、いくつかの行の後に "join"があります。

「未定義の動作」のようなものかもしれませんが、正確には何か分かりません。 (この場合はthisで)

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 
+6

スレッドを作成した後はどうなりますか?あなたはそれに '参加するのですか? – doctorlove

+3

@doctorloveは、これが生涯の問題のように見えることは、スレッドがKlassインスタンスよりも長生きしているため、このポインタがぶら下がっているところです。適切な場所に参加することで、これを防ぐことができます。しかし、私たちは提示された文脈に基づいて確信することはできません。 – stefaanv

+0

@doctorlove stefaanvこんにちは、お返事ありがとうございます。実際には、デバッガとログは、std :: threadのctorが呼び出された直後にプログラムがダウンしていることを示し、「join」は数行後にあります。私は問題が "参加"ではないと思う。そして、私が議論せずに "myfunc"を呼び出すと、すべてがうまくいくという質問にも言及しました。 – Wizmann

答えて

1

あなたはいつもあなたが参加(あるいは切り離し)を確認する必要がありますthread、そうでない場合は、特にオブジェクトを使用してスレッドをmainを残します:

コールスタックはこのようなものです(時には)問題を引き起こします。

//... details omitted... 

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

アンソニー・ウィリアムのスレッドblogがこれを詳細に調べます。 2番目のものと非常に類似した例では:

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

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

彼は

を言うあなたはこの小さなアプリケーションをコンパイルして実行した場合、どうなりますか?それは 私たちが望んでいたようにこんにちは?まあ、実際には何の話もありません。それは の場合とそうでない場合があります。この単純なアプリケーションを私のマシン上で数回 実行したところ、出力は信頼できませんでした。たびたび改行で "hello"を出力しました。 改行せずに "hello"を出力することがあり、何も出力しないことがありました。どうしたの? 確かに、このような単純なアプリは予想通りに動作するはずですか?

彼はその後、私は上記したよう joinを使用してのアイデアを紹介し、言う

問題は、私たちのスレッドが終了するのを我々は待っていないです。 の実行がmain()の終了に達すると、プログラムは終了します。 他のスレッドが何をしていても。

関連する問題