собсно, сам минимальный тест:
#include <iostream> void user_main(int argc, char ** argv) { int cnt = 1; // код пользователя while( true) { ///-----------------| /// Бобик сдох... | ///-----------------| std::cout << "\r" << ++cnt; } } #include <boost/thread.hpp> #include <boost/chrono.hpp> void foo( int argc, char ** argv) { boost::chrono::microseconds maxduration{5'000'000}; using namespace boost::chrono; auto start = high_resolution_clock::now( ); auto elapsed_times = [&start]( ) { auto finish = high_resolution_clock::now( ); std::cout << "Elapsed time: " << std::fixed << float( duration_cast<microseconds>( finish - start).count( )) / 1'000'000 << " s\n"; }; boost::thread work( [] ( int argc, char ** argv) -> void { user_main( argc, argv); } , argc , argv ); if( work.try_join_for( maxduration)) { elapsed_times ( ); } else { elapsed_times ( ); std::cout << "Time Limit Exceeded\n"; work.interrupt( ); ///<—- ??? } } int main( int argc, char ** argv) { foo ( argc, argv); std::cout << "PROGRAMM GOOD FINISHED\n"; /// зависший поток продолжает кутить ... std::cin.get( ); }
???
Получить нативный хэндл и вызвать Terminate из winapi, или любой подобный способ, ничего лучше нет
/A\
> Получить нативный хэндл и вызвать Terminate из winapi, или любой подобный
> способ, ничего лучше нет
так чо я спрашиваю, неужто хвалённый буст это не умеет?
а Terminate не накроет основной поток вместе с зависшим???
я мог такой детач и в std сделать(или уже давно сделал).
нафиг тогда буст мне был нужен(((
xlat-code
> неужто хвалённый буст это не умеет?
буст умеет, ты не умеешь
вот тут целый набор способов, но почему-то виндовый TerminateThread() проигнорирован
https://habr.com/ru/post/306332/
ну и вот это пять
xlat-code
> // код пользователя
> while(true)
> {
чего бы не сделать?
volatile bool m_run;
внутри класса с функтором, который ставить в false перед join()
#!
> чего бы не сделать?
длл с плагинами будут городить все кто сможет и захочет.
и мало ли что они там нагородят?
#!
> внутри класса с функтором, который ставить в false перед join()
это если бы я целиком писал, то да.
xlat-code
> длл с плагинами будут городить все кто сможет и захочет
дочерний процесс сделай, с которым общаться по stdin/stdout
а то вдруг segfault ошибок там налепят, и уронят вообще всё, а так можно будет перезапустить
ещё можно над скриптосистемой подумать
#!
+1
xlat-code
> длл с плагинами будут городить все кто сможет и захочет.
> и мало ли что они там нагородят?
И ты теперь собираешься прибивать поток, который создала чужая длл с плагином? А как ты будешь понимать завис поток, или всё еще работает?
MrShoor
2)увеличивать глобальный счетчик. такой софтверный ватчдог будет. если этот поток конечно имеет вход в твою функцию.
у меня вот проблема была с шелл функцией открывающей диалог выбора файлов. она иногда зависала. видимо у меня в винде какие то косяки или расширения - компоненты в системы стоят корявые, которые за показ миниатюр отвечают.
не получилось даже вызывать ее в отдельном потоке. потому что там создается системный поток который все равно замораживает основной тред процесса. я даже не понял как так =/
а попытка убить дочерний поток с диалогом автоматически схлопывает процесс.
Noir
> 2)увеличивать глобальный счетчик. такой софтверный ватчдог будет. если этот
> поток конечно имеет вход в твою функцию.
Так а вход в твою функцию никак не поможет? Ну вот вошел поток в твою функцию, вышел... и? Завис поток или нет?
> у меня вот проблема была с шелл функцией открывающей диалог выбора файлов. она
> иногда зависала.
Вангую что проблема была как-то связана с твоим оконным циклом. Дело в том, что все диалоги винды начинают крутить оконный цикл внутри себя, т.е. вызываешь ты ShowDialog а там внутри:
procedure ShowDialog; begin while GetMessage(msg) begin end; end;
Т.е. например теперь все твои обработчики WM_PAINT будут вызываться изнутри ShowDialog-а.
И есть еще один подводный камень. WM_PAINT почему-то имеет более высокий приоритет чем WM_TIMER (что на мой взгляд - огромная промашка видны). Поэтому пока у тебя в очереди WM_PAINT, то WM_TIMER не обработается. А системные диалоги как раз занимаются тем, что создают таймер.
#!
> volatile
Только не волатайл, а атомик.
Имбирная Ведьмочка
> а атомик
а разве volatile не строже чем atomic memory_order::relaxed?
partial write на одном bool вроде как не страшен, и писатель ровно один
в общем навскидку не припоминаю проблем с выходом приложения
MrShoor
не. я пытался вызвать это в отдельном потоке. но зависание диалога все равно приводила к печальном концу приложения. кароче это ниче не поменяло.
если диалог созданный GetOpenFileName(ofn) зависал на отображении миниатюр то все.
приложение не отвечает. ваще похрен что попытка была в другом треде) создаваемый системой поток на выбор картинки каким то образом овладевает главным потоком процесса. либо заворачивает его туда самого (и это очень дерзко с его стороны!).
procedure TOpenPictureThread.Execute; var ofn: TOpenFilename; buffer: array [0..MAXSIZE-1] of Char; OutString: string; dwerr:DWORD; begin try fillchar(ofn,sizeof( ofn),0); fillchar( buffer,sizeof( buffer),0); ofn.lStructSize := SizeOf( ofn); ofn.hWndOwner := FOwner; ofn.hInstance := HInstance; ofn.lpstrFilter := NFilter; ofn.lpstrFile := buffer; ofn.nMaxFile := MAXSIZE; ofn.Flags := OFN_FILEMUSTEXIST or OFN_PATHMUSTEXIST or OFN_LONGNAMES or OFN_EXPLORER or OFN_HIDEREADONLY; ofn.lpstrTitle := OurTitle; if GetOpenFileName( ofn) then begin OutString := OutString + FullPathName + ofn.lpstrFile + #13#10; OutString := OutString + FullName + ExtractFileName( ofn.lpstrFile) + #13#10; OutString := OutString + FullName + ExtractFileExt( ofn.lpstrFile); if assigned( FOpenPictureCallback)then begin FResult:= ofn.lpstrFile; Synchronize( ThreadProc); end; end else begin dwerr:=CommDlgExtendedError; if dwerr<>0 then showmessage( 'error dialog create : '+ErrorToS( dwerr)); end; except on E:exception do showmessage( 'error ' + e.Message); end; end;
Noir
> если диалог созданный GetOpenFileName(ofn) зависал на отображении миниатюр то
> все.
> приложение не отвечает.
Очень странно, что приложение не отвечает, т.к. этот диалог используется во многих приложениях. При этом отображение миниатюр - это посути часть общего проводника. Ну т.е. с большой вероятностью у тебя бы сам проводник зависал.
Прибивание потока не завершает те операции, которые он там у себя выполнял. Как правило, это создает проблемы, а не решает их. Операция крайне не рекомендована к использованию. Система просто снимает его с выполнения, а что у него внутри ей по барабану. Если просто намусорит по памяти, это еще малая беда, как правило последствия хуже.
Хочешь завершить поток? Попроси его самого завершиться.