Primo : When i type : hbmk_b32.bat -w2 -mt -gui mttest00.prg
then on screen i have : C:\harbour\tests\mt>hbmk_b32.bat -w2 -mt -gui mttest00.prg Error F0034 Bad command line option '.' Syntax: c:\Harbour\bin\harbour.exe <file[s][.prg]|@file> [options] [...] but exe without name is created : ║ Name │ Size │ Date │Time ║ ║.. │<UP--DIR>│08-11-02│12:57║ ║.exe │ 549 888│08-11-02│12:57║ ║.tds │ 458 752│08-11-02│12:57║ ║mttest00 exe│ 572 928│08-11-02│12:57║ ║mttest00 prg│ 124│08-11-02│08:02║ Secudo : I have write Mutex test : >>>>>>>>>>>>>>>>>>> #include "inkey.ch" #ifdef __PLATFORM__WINDOWS REQUEST HB_GT_WVT_DEFAULT #define THREAD_GT hb_gtVersion() #else REQUEST HB_GT_STD_DEFAULT #define THREAD_GT "XWC" #endif /* 2 x mutex to synchronize thteads*/ STATIC critical, flag Function main() // s_mainThreadID := hb_threadSelf() Local aThreads := {} Local appName := { ; { 'app_01', '{|| 1}'}, ; { 'app_02', '{|| 2}'}, ; { 'app_03', '{|| 3}'}, ; { 'app_04', '{|| 4}'}, ; { 'app_05', '{|| 5}'}, ; { 'app_06', '{|| 6}'}, ; { 'app_07', '{|| 7}'}, ; { 'app_08', '{|| 8}'}, ; { 'app_09', '{|| 9}'}, ; { 'app_10', '{|| 10}'}, ; { 'app_11', '{|| 11}'}, ; { 'app_12', '{|| 12}'}, ; { 'app_13', '{|| 13}'}, ; { 'app_14', '{|| 14}'}, ; { 'app_15', '{|| 15}'}, ; { 'app_16', '{|| 16}'}, ; { 'app_17', '{|| 17}'}, ; { 'app_18', '{|| 18}'}, ; { 'app_19', '{|| 19}'}, ; { 'app_20', '{|| 20}'}} Local n critical := hb_mutexCreate() flag := hb_mutexCreate() ? "I'm Parent, to order have first generate window ... " For n := 1 to 5 * Len( appName) aadd( aThreads, hb_threadStart( @runApp(), appName[ hb_Random( 1, Len( appName))], Len( aThreads) + 1)) Next ? "Waiting for threads" while inkey() != K_ESC if hb_threadWait( aThreads, .1, .t. ) == len( aThreads ) // all threads ends wait 'Wątki wyszły, konczymy test ...' exit endif enddo Return Nil *------------------ Function runApp( appName, count) STATIC appStorage := {} Local n, c := Upper( appName[1]), find := { |x| x[ 1] == c}, executeTime := 60 // If hb_Random() > .2 ; hb_gtReload( THREAD_GT ) // End hb_gtReload( THREAD_GT ) ? "Here thread ", hb_threadSelf(), ". I mus run ", c hb_gtInfo( 26, Str( count, 3, 0) + ' - ' + c) InKey( hb_Random()) If ( n := Ascan( appStorage, find)) != 0 ? 'The app is in storage, I can run it - ', appStorage[ n, 2]:Eval() executeTime := 1 Else While !Semaphore( c, 1) ; hb_idleSleep( .3) End If ( n := Ascan( appStorage, find)) != 0 Semaphore( c, 0) hb_gtInfo( 26, 'Another process is win !!!') ? 'Another thread was compiled it. I can run it. ', appStorage[ n, 2]:Eval() executeTime := 5 Else ? "I have first acces, I mus compile and next can run it! : ", appName[ 2] begin sequence hb_mutexLock( flag) AADD( appStorage, { c, &( appName[ 2])}) n := Len( appStorage) appName[ 2] := 'error error error' // to generate error when another thread can acces to this element! always hb_mutexUnLock( flag) Semaphore( c, 0) end sequence ?? appStorage[ n, 2]:Eval() End End InKey( executeTime) Return Nil *------------------ Function Semaphore( semafor, action) Static semStor := {} Local succes := .t., n switch action case 0 hb_mutexLock( flag) If (n := Ascan( semStor, semafor)) != 0 ; Adel( semStor, n) ; Asize( semStor, Len( semStor) - 1) End hb_mutexUnLock( flag) exit case 1 // default If (n := Ascan( semStor, semafor)) != 0 ; succes := .f. Else hb_mutexLock( flag) If (n := Ascan( semStor, semafor)) != 0 ; succes := .f. Else AADD( semStor, semafor) End hb_mutexUnLock( flag) End endswitch Return succes *------------------ <<<<<<<<<<<<<<<<<<< All works ok., but I don't see window with string 'Another thread was compiled it. I can run it. ' To simulate ral life, I add Inkey( ... ) : >>>>>>>>> Function runApp( appName, count) STATIC appStorage := {} Local n, c := Upper( appName[1]), find := { |x| x[ 1] == c}, executeTime := 60 // If hb_Random() > .2 ; hb_gtReload( THREAD_GT ) // End hb_gtReload( THREAD_GT ) ? "Here thread ", hb_threadSelf(), ". I mus run ", c hb_gtInfo( 26, Str( count, 3, 0) + ' - ' + c) InKey( hb_Random()) If ( n := Ascan( appStorage, find)) != 0 ? 'The app is in storage, I can run it - ', appStorage[ n, 2]:Eval() executeTime := 1 Else While !Semaphore( c, 1) ; hb_idleSleep( .3) End If ( n := Ascan( appStorage, find)) != 0 Semaphore( c, 0) hb_gtInfo( 26, 'Another process is win !!!') ? 'Another thread was compiled it. I can run it. ', appStorage[ n, 2]:Eval() executeTime := 5 Else ? "I have first acces, I mus compile and next can run it! : ", appName[ 2] begin sequence hb_mutexLock( flag) AADD( appStorage, { c, &( appName[ 2])}) *>>> HERE ! InKey( hb_Random()) // delay to compile big app *<<< n := Len( appStorage) appName[ 2] := 'error error error' // to generate error when another thread can acces to this element! always hb_mutexUnLock( flag) Semaphore( c, 0) end sequence ?? appStorage[ n, 2]:Eval() End End InKey( executeTime) Return Nil <<<<<<<<<<<<<<<<<<<<<<<<<<< AND IN THIS VERSION ALL THREADS ARE HANGS !!!! When I change to to this version : >>>>>>>>>>>>>>>>>>>>>>> Function runApp( appName, count) STATIC appStorage := {} Local n, c := Upper( appName[1]), find := { |x| x[ 1] == c}, executeTime := 240, delay // If hb_Random() > .2 ; hb_gtReload( THREAD_GT ) // End hb_gtReload( THREAD_GT ) ? "Here thread ", hb_threadSelf(), ". I mus run ", c hb_gtInfo( 26, Str( count, 3, 0) + ' - ' + c) InKey( hb_Random()) If ( n := Ascan( appStorage, find)) != 0 ? 'The app is in storage, I can run it - ', appStorage[ n, 2]:Eval() executeTime := 1 Else While !Semaphore( c, 1) ; hb_idleSleep( .3) End If ( n := Ascan( appStorage, find)) != 0 Semaphore( c, 0) hb_gtInfo( 26, 'Another process is win !!!') ? 'Another thread was compiled it. I can run it. ', appStorage[ n, 2]:Eval() executeTime := 5 Else ? "I have first acces, I mus compile and next can run it! : ", appName[ 2] begin sequence hb_mutexLock( flag) AADD( appStorage, { c, &( appName[ 2])}) *---------- HERE !!!! // InKey( hb_Random()) // delay to compile big app delay := Seconds() + 1 While seconds() < delay End *----------- n := Len( appStorage) appName[ 2] := 'error error error' // to generate error when another thread can acces to this element! always hb_mutexUnLock( flag) Semaphore( c, 0) end sequence ?? appStorage[ n, 2]:Eval() End End InKey( executeTime) Return Nil <<<<<<<<<<<<<<<<<<<<<<< All apps was quickened, and many window has label "Another thread was compiled it. I can run it.", that inform about other winner process. Mutex are PRETTY and make good job. But my ask is : We don't can use InKey( ... ) when some kind mutex is locked ? Regards, Marek Horodyski
_______________________________________________ Harbour mailing list Harbour@harbour-project.org http://lists.harbour-project.org/mailman/listinfo/harbour