Программа зависает после вызова std::thread::join
Имеется следующий код
std::atomic<bool> StopThread=FALSE;//находится внутри класса
void Finder::StartThread(CString path)
{
if( ThreadFindFile.joinable() )
{
StopThread = TRUE;
ThreadFindFile.join();
StopThread = FALSE;
}
imageIndex = 0;
Tmp.ListView.DeleteAllItems();
ThreadFindFile=std::thread( (&Finder::findFile),this , path, std::ref(imageIndex) );
}
Программа зависает каждый раз когда доходит до join(), с detach() все работает хорошо. Но вопрос почему на join такое происходит?
Сначала думал что происходит взаимоблокировка потока, но после изучения оказалось что такой проблемы нет.
StopThread является флагом внутри Finder::findFile, если она ==TRUE, то делаю return из функции.
Update Добавил код функции которая вызывается потоком
void Finder::findFile( CString szPath, int& i )
{
CFindFile FileSearch;
CString S = szPath + TEXT( "\\*.*" );
BOOL bFlag = FileSearch.FindFile( S );
if( !bFlag )
{
MessageBox( ListView_hWnd, TEXT( "Error" ), TEXT( "File not found" ), 0 );
}
else
{
do
{
if( FileSearch.IsDots() )
{
continue;
}
else
{
if( StopThread )
{
return;
}
if( FileSearch.IsDirectory() )
{
findFile( FileSearch.GetFilePath(), i );
}
view_List( FileSearch.GetFileName(), i, FileSearch.GetFilePath() );
i++;
}
} while( FileSearch.FindNextFileW() );
FileSearch.Close();
}
Tmp.ListView.SetImageList( hSmall, 1 );
}
void Finder::view_List( CString name, int i, CString path )
{
LVITEM lvItem;
SHFILEINFOW lp{};
CString nameWithoutEx = std::get<0>( split( name ) );
CString extention = std::get<1>( split( name ) );
lvItem.mask = LVIF_IMAGE | LVIF_TEXT;
lvItem.state = 0;
lvItem.stateMask = 0;
lvItem.iItem = i;
lvItem.iImage = i;
lvItem.iSubItem = 0;
lvItem.pszText = const_cast< LPWSTR >( nameWithoutEx.GetString() );
lvItem.cchTextMax = nameWithoutEx.GetLength();
Tmp.ListView.InsertItem( &lvItem );
Tmp.ListView.SetItemText( i, 1, extention.GetString() );
Tmp.ListView.SetItemText( i, 2, path.GetString() );
DWORD num = GetFileAttributesW( path.GetString() );
SHGetFileInfoW( path.GetString(), num, &lp, sizeof( lp ),
SHGFI_SYSICONINDEX | SHGFI_ICON | SHGFI_USEFILEATTRIBUTES );
hSmall.AddIcon( lp.hIcon );
DestroyIcon( lp.hIcon );
}
Ответы (1 шт):
join ждет, пока поток завершится. А если потом чем то занят (например, перекладывает с пустого в порожнее или крутит бесконечный цикл) и не думает завершатся, то ждать join будет долго долго.
Если же потоку сделали detach, то как бы говорите "поток, ты себе там работай, join тебе звать никто не будет". И все. И ничего не "зависает".
Нужен ли join или нет в Вашей конкретной ситуации? а кто его знает, никто же не знает, чем поток занимается и почему Вы решили его подождать. Если результат работы потока Вам очень нужен, то подождать стоит. Но вот ждать в gui потоке точно не стоит. Плюс, Ваша функция называется "запустить поток", а она на самом деле пытается его подождать.