Newsgroup: it.comp.programmare.win32
Titolo: Sincronizzazione Threads

 detto che io debba fare il fiorista....  [Morgan]  <
Visitate il mio sito:
http://digilander.iol.it/Superpork

 Johnny
Il tuo algoritmo e' , a mio modesto parere, quantomeno discutibile. E'
concettualmente  sbagliato continuare l'esecuzione di un thread worker
quando  ha ultimato  il proprio compito. Se noti hai costruito un loop
infinito  che  assomiglia  alla  gestione messaggi  di  ogni  generica
applicazione   Win32.  Perche'  allora  non  delegare  il  compito  di
controllo  a  chi e'  fondamentalmente  preposto  a farlo?  Una  volta
terminata  l'esecuzione del thread mandi semplicemente un messaggio al
processo  padre il quale lo elaborera' e agira' di conseguenza. Se hai
delle sezioni dati da condividere tra i threads e il main process puoi
utilizzare  una critical  section per  proteggere quell'area  dati; se
devi  vincolare l'accesso a una risorsa a un numero limitato di thread
puoi usare un semaforo; se hai la necessita' di verificare l'attivita'
del thread usa GetExitCodeThread preceduto da una WaitForSingleObject.
Tutto questo dal main process e non artigianalmente dal thread. ;^)
Ciao.
Il Michett@
--

 Johnny
Personalmente sono abituato a sganciare l'interfaccia utente dai processi
di calcolo ed esecuzione comandi. Per questo motivo forse ti ho indotto in
errore. Visto le tue necessita' di calcolo realtime non ti conviene usare
la riallocazione del thread a ogni ciclo, si rischia un overhead  oltre a
una notevole frammentazione. Prova questa soluzione:
BOOL bThreadsRunning;
DWORD WINAPI ChildThreadProc( HWND hWnd )
{
    char szBuffer[256];         // work area for print formatting
    HANDLE hThread = GetCurrentThread();
    HANDLE hAutoEvent = OpenEvent( SYNCHRONIZE | EVENT_MODIFY_STATE,
                                   FALSE, "EXAMPLE-AUTOEVENT");
    // Pump up the volume, pump up the volume... 8^)
    SetThreadPriority(hThread, THREAD_PRIORITY_TIME_CRITICAL);
    ResetEvent(hAutoEvent);
    while (bThreadsRunning) {
        // simulate to do something
        wsprintf( szBuffer, "Thread %x is working...",
            GetCurrentThreadId() );
        SendMessage( hWnd, WM_USER, 0, (LPARAM)szBuffer );
        Sleep( 10*GetCurrentThread() );
        // signal thread computation end
        wsprintf( szBuffer,
            "Thread %x is waiting other threads execution end...",
            GetCurrentThreadId() );
        SendMessage( hWnd, WM_USER, (WPARAM)1, (LPARAM)szBuffer );
        // ..and wait the other threads
        WaitForSingleObject( hAutoEvent, INFINITE );
    }
    CloseHandle( hAutoEvent );
    ExitThread( TRUE );
}
// Windows message procedure.
LRESULT CALLBACK WndProc( HWND hWnd, UINT uMsg, WPARAM wParam,
    LPARAM lParam )
{
    static HANDLE hAutoEvent = 0;
    switch (uMsg)
    {
     // Make an auto-reset event with initial state of nonsignaled.
        case WM_CREATE:
            hAutoEvent = CreateEvent( NULL, FALSE, FALSE,
                "EXAMPLE-AUTOEVENT");
            return DefWindowProc( hWnd, uMsg, wParam, lParam );
        case WM_DESTROY:
            if ( hAutoEvent )
                CloseHandle( hAutoEvent );
            PostQuitMessage( 0 );
            break;
        case WM_USER:
            {  // Message to show synchronization actions.
                TCHAR szBuffer[101];
                int j;
                static int i = 0;
                static int row = 0;
                static int msg_num = 1;
                HDC hDC = GetDC( hWnd );
                FillMemory( szBuffer, 100, 32 );
                TextOut( hDC, 0, row, szBuffer, 100 );
                wsprintf( szBuffer, "%3d: %s", msg_num++,
                    (LPTSTR)lParam );
                TextOut(hDC, 0, row, szBuffer, lstrlen( szBuffer ));
                row = row>200 ? 0 : row+20;
                ReleaseDC( hWnd, hDC );
                // Check threads end
                if (wParam) {
                    i++;
                    if (i == 4) {
                        for (j=0;j<i;j++)
                            SetEvent(hAutoEvent);
                        i=0;
                    }
                }
            }
            break;
            case WM_COMMAND:       // process menu items
                switch ( LOWORD( wParam )  )
                    {
                        case IDM_TEST:
                            {
                                unsigned int id[4], i;
                                bThreadsRunning= TRUE;
                                for (i=0;i<4;i++) {
                                    id[i]=0;
                                    CreateThread( NULL, 0,
                                    ChildThreadProc, hWnd,
                                    0, &id[i] );
                                }
                            }
                            break;
                        case IDM_EXIT:
                            DestroyWindow( hWnd );
                            break;
                        case IDM_KILLER:
                            bThreadsRunning = FALSE;
                            break;
                    }
                    break;
            default:
                return DefWindowProc( hWnd, uMsg, wParam,
                    lParam );
    }
    return 0;
}
..dovrebbe funzionare.
Ciao.
Il Michett@
--
p.s. Ho scritto i commenti in inglese volutamente. Magari
puo' servire a qualcun'altro.

 wrote in message
8tcd7v$lvfca$1...@ID-55767.news.dfncis.de...


 Johnny
Prego e buon lavoro.
Ciao.
Il Michett@
--