c++ - Non blocking thread synchronization -
i have dialog box button, , other controls.
when button pressed worker thread spawned.
for easier discussion, let thread function lengthy job.
each time button clicked, new thread should spawn , stuff.
dialog box should not blocked while worker threads job, since user should able minimize it, click on other controls , on.
on wikipedia, have found term lock-free algorithm, refers non blocking thread synchronization.
this why interested in non blocking thread synchronization. believe ensure behavior need.
i new multithreading, did find articles/answered questions here, , have read documentation on microsoft it.
most of these use following algorithms:
1.
main thread declares volatile variable ( int or bool ) , passes worker thread. worker thread checks variable in loop, , if not set indicate termination, continues work. when needs terminated, parent thread sets variable.
2.
there vast documentation on microsoft's website synchronization. there, have found mutexes, critical sections, interlocks , more.
the problem these block parent thread ( waitforsingleobject or waitformultipleobjects api ), until worker thread finished.
also, searching here, have found recent question ( abort thread when dialog box close button clicked ) has helped me make start.
in order solve problem break question multiple ones, , post them separately, in order respect rules of stackoverflow.
so first question is:
which api/algorithm should use achieve non blocking thread synchronization, me achieve dialog box behaves described above ?
i appreciate links tutorials or code examples, if possible, since had no luck google ( also, developers learn best through code/pseudo code ).
i present initial tries these code snippets bellow, in case prove useful:
// thread function dword winapi mythread() { int result = 0; // if( /** ok **/ ) return result; else { result = 1; return result; } }
now dialog box:
// button clicked handler case idc_button1: { // create thread dword tid; handle th = createthread( null , 0 , (lpthread_start_routine)mythread , null , 0 , &tid ); if( !th ) enddialog( hwnd, idcancel ); closehandle( th ); } break; case idcancel: enddialog( hwnd, idcancel ); break;
at point, when run program, activate dialog box, , click on button, worker thread spawn up, , if wait finish.
yet if close dialog box early, nature of problem same in question have found here ( think waitformultipleobjects in idcancel handler can partialy fix leave post ).
edit #1:
i have posted new code, reflect progress , problems have faced.
important note:
instead of firing multiple threads, have hidden button starts thread, once pressed.
this means user have wait first thread finish, before he/she able activate second one.
this done easier debugging.
defined custom messages indicate if thread exited gracefully, or error happened.
#define wm_thread_ok ( wm_app + 1 ) #define wm_thread_error ( wm_app + 2 )
added data structure passed thread can communicate dialog, , can aborted properly
struct data { hwnd hwnd; bool bcontinue; };
reworked thread function send messages dialog box can notify dialog errors, or graceful end.
new code ( based on example book charles petzold-programming windows 5th ed. ):
// thread function dword winapi mythread( lpvoid lpvoid ) { hresult hr; volatile data *data = ( data* )lpvoid; try { for( int = 0; < 10 && data->bcontinue; i++ ) { hr = // if( failed(hr) ) throw _com_error(hr); } // once leave loop, check if thread aborted, or if( ! ( data->bcontinue ) ) { // thread aborted, cleanup , exit // cleanup return 0; } // if went well, cleanup, , "say" dialog box // cleanup here sendmessage( data->hwnd, wm_thread_ok, 0, 0 ); return 0; // exit gracefully } catch( _com_error & ) { // cleanup sendmessage( data->hwnd, wm_thread_error, 0, 0 ); return 1; } }
here new code dialog box ( note: dialog box modeless ):
static data data; handle th = null; // button clicked handler case idc_button1: { // create thread dword tid; th = createthread( null , 0 , (lpthread_start_routine)mythread , (lpvoid)&data, 0 , &tid ); if( !th ) destroywindow( hwnd ); // hide button activates thread showwindow( getdlgitem( hwnd, idc_button1 ), sw_hide ); } break; case wm_thread_ok: if( th ) closehandle( th ); showwindow( getdlgitem( hwnd, idc_button1 ), sw_show ); break; case wm_thread_error: if( th ) closehandle( threadhandle ); messagebox( hwnd, l"error", l"error", mb_iconerror ); break; case idcancel: data.bcontinue = false; // set thread abortion flag if( th ) { // after comment out below statement, thread aborts // waitforsingleobject( th, infinite ); closehandle( th ); } destroywindow( hwnd ); // dialog box modeless one! break;
my question is: there mistakes in code ? can improved, , how ?
thank you.
you dont need lock free synchronization. fire threads , have them signal objects when complete. non-blocking call on sync handle if dont want block ui thread
ie
waitformultipleobjects(n,lphandles, 0, 0);
the last 0 says return rather wait if object(s) not signalled
Comments
Post a Comment