Программа зависает после вызова 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 шт):

Автор решения: KoVadim

join ждет, пока поток завершится. А если потом чем то занят (например, перекладывает с пустого в порожнее или крутит бесконечный цикл) и не думает завершатся, то ждать join будет долго долго.

Если же потоку сделали detach, то как бы говорите "поток, ты себе там работай, join тебе звать никто не будет". И все. И ничего не "зависает".

Нужен ли join или нет в Вашей конкретной ситуации? а кто его знает, никто же не знает, чем поток занимается и почему Вы решили его подождать. Если результат работы потока Вам очень нужен, то подождать стоит. Но вот ждать в gui потоке точно не стоит. Плюс, Ваша функция называется "запустить поток", а она на самом деле пытается его подождать.

→ Ссылка