Newsgroup: it.comp.programmare.win32
Titolo: Multithread

Continuo a non riuscire a risolvere il mio problema.
Devo gestire 2 thread che vanno in conflitto l'uno con l'altro. (access
violation tentando di accedere ad un campo). Qualcuno mi sa dare qualche
dritta in proposito? Critical Section e read and exclusive write ho capito
cosa sono ma non mi e' molto chiaro come funzionano.
Qualcuno mi puo' dare consigli o( meglio) postarmi un codice che mi illustri
come funzionano?
Grazie 1000
Max

 ha scritto nel messaggio
news:9723352...@spyke.goldnet.it...

La trattazione teorica è piuttosto vasta, per quella ti rimando a un buon
libro sui sistemi operativi, il Tanenbaum ad esempio è ottimo su questo
argomento (mentre fa pena il S.O. presentato come esempio, Minix). In linea
di massima comunque qualunque sistema mette a disposizione delle primitive
di sincronizzazione chiamate semafori, il cui funzionamento è più o meno
questo (scrivo in pseudo C):
// variabili condivise
char *buffer;    // area critica
Semaphore s;    // il tipo preciso dipende dal S.O.
void crit_routine(void)
{
    P(s);    // controlla la disponibilita' di S
    strcpy(buffer, "prova");    // eventuali altre operazioni
    V(s);    // rilascia il lock
    return;
}
Il semaforo è in pratica un flag che regola l'accesso alle sezioni critiche,
P() e V() sono i nomi assegnati canonicamente alle procedure per attivare e
rilasciare il lock, ma secondo il S.O. utilizzato potrebbero chiamarsi
lock() e unlock(), oppure anche pippo() e pluto() se è per questo :-) e lo
stesso ovviamente vale per il tipo della variabile da dichiarare come
semaforo; potresti persino avere a disposizione una classe per la gestione
delle sezioni critiche, dotata di metodi appropriati (come i monitor in
Java); su questo non posso aiutarti e ti rimando alla documentazione del
S.O. e delle librerie che usi. Il succo del discorso è comunque che un
semaforo agisce da flag per la disponibilità di una risorsa condivisa, e
quando un processo esegue la chiamata P() continua solo se questa è libera,
altrimenti si mette in attesa e il sistema lo risveglia non appena un altro
processo esegue la V(), liberando l'accesso.
Spero di esserti stato d'aiuto...
Massimo

violation tentando di accedere ad un campo).
Sei sicuro che non sia un problema di puntatori errati a prescindere
dalla 'concorrenza'?
Luc.

 >violation tentando di accedere ad un campo).
Vediamo se il tuo prob č simile a quello che
avevo io.
Hai dichiarato due thread nel seguente modo:
static UINT thread1(LPVOID pParam);
static UINT thread2(LPVOID pParam);
nel file Miaclasse.h
Ora quando all'interno dei thread cerchi di
accedere ad una variabile di Miaclasse ti viene
dato l'errore specificato. Ebbene per risolvere
questo problema devi fare cosi:
lancio thread:
void Miaclasse::Lancio()
{
  AfxBeginThread(thread1,this);
  AfxBeginThread(thread2,this);
}
definizioe thread:
UINT Miaclasse::thread1(LPVOID pParam)
{
  Miaclasse *This=(Miaclasse *)pParam;
  //accesso varibile
  This->miavariabile=(rvalue);
}
Questo problema deriva dal fatto della
dichiarazione statica dei thread. Spero di aver
risolto il tuo prob.
bye
Sent via Deja.com 
http://www.deja.com/
Before you buy.

 funzionano?
Ti  propongo  l'esempio fornito  con "Win32  API Blible" nella sezione
riguardante  la sincronizzazione dei thread e process. A tuo beneficio
ti  ricordo  che le Critical  Section servono a proteggere solo codice
non-rientrante(*)  di threads  di  UN  processo. Per  sincronizzazioni
multiprocesso  devi usare i mutex, semaphore o event. Se c'e' qualcosa
che non ti e' chiaro puoi chiedere...
(*)   Per  rientrante   considero  quei  thread  safe  che  non  fanno
affidamento  su nessun  tipo di meccanismo di sincronizzazione e usano
solo dati PRIVATI nello svolgimento delle loro operazioni, permettendo
di  fatto un  "safe  multithreading" senza  sincronizzazione di  sorta
(parallel operations).
Ciao.
Il Michett@
--
#include <windows.h>
#define IDM_EXIT           100
#define IDM_TEST           200
#define IDM_ABOUT          300
#define DLG_VERFIRST        400
#define DLG_VERLAST         404
LRESULT CALLBACK WndProc(HWND, UINT, WPARAM, LPARAM);
LRESULT CALLBACK About  (HWND, UINT, WPARAM, LPARAM);
LRESULT CALLBACK WndProc( HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM
lParam );
HINSTANCE hInst;   // current instance
LPCTSTR lpszAppName = "MyApp";
LPCTSTR lpszTitle   = "My Application";
CRITICAL_SECTION cs;
int APIENTRY WinMain( HINSTANCE hInstance, HINSTANCE hPrevInstance,
                      LPTSTR lpCmdLine, int nCmdShow)
{
   MSG      msg;
   HWND     hWnd;
   WNDCLASS wc;
   wc.style         = CS_HREDRAW | CS_VREDRAW;
   wc.lpfnWndProc   = (WNDPROC)WndProc;
   wc.cbClsExtra    = 0;
   wc.cbWndExtra    = 0;
   wc.hInstance     = hInstance;
   wc.hIcon         = LoadIcon (hInstance, lpszAppName);
   wc.hCursor       = LoadCursor(NULL, IDC_ARROW);
   wc.hbrBackground = (HBRUSH)(COLOR_WINDOW+1);
   wc.lpszMenuName  = lpszAppName;
   wc.lpszClassName = lpszAppName;
   RegisterClass( &wc );
   hInst = hInstance;
   hWnd = CreateWindow( lpszAppName,
                        lpszTitle,
                        WS_OVERLAPPEDWINDOW,
                        CW_USEDEFAULT, 0,
                        CW_USEDEFAULT, 0,
                        NULL,
                        NULL,
                        hInstance,
                        NULL
                      );
   if ( !hWnd )
      return( FALSE );
   ShowWindow( hWnd, nCmdShow );
   UpdateWindow( hWnd );
   while( GetMessage( &msg, NULL, 0, 0) )
   {
      TranslateMessage( &msg );
      DispatchMessage( &msg );
   }
   return( msg.wParam );
}
// Child thread procedure.
DWORD WINAPI ChildThreadProc(HWND hWnd)
{
   TCHAR szBuffer[256];    // Work area for print formatting.
   wsprintf( szBuffer, "Thread %x waiting for critical section",
GetCurrentThreadId() );
   SendMessage( hWnd, WM_USER, 0, (LPARAM) szBuffer );
   // Enter protected code.
   EnterCriticalSection( &cs );
   wsprintf( szBuffer,"Thread %x in critical section",
GetCurrentThreadId() );
   SendMessage( hWnd, WM_USER, 0, (LPARAM) szBuffer );
   Sleep( 5000 );  // This is where our critical code would go if we had
some.
   // All done now, let someone else in.
   LeaveCriticalSection( &cs );
   wsprintf( szBuffer,"Thread %x has exited critical section",
GetCurrentThreadId() );
   SendMessage( hWnd, WM_USER, 0, (LPARAM) szBuffer );
   ExitThread(TRUE);
}
// Main Window Procedure
LRESULT CALLBACK WndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
{
   switch (uMsg)
   {
           case WM_CREATE:  // A critical section must be initialized before
it is used.
                   InitializeCriticalSection(&cs);
                   return DefWindowProc( hWnd, uMsg, wParam, lParam );
           case WM_COMMAND:       // Process menu items.
                   switch ( LOWORD( wParam ) )
                   {
                        case IDM_TEST:
                        {
                           DWORD dwChildID;
                           CreateThread( NULL, 0, ChildThreadProc, hWnd, 0,
&dwChildID );
                        }
                        break;
                        case IDM_EXIT:
                           DestroyWindow( hWnd );
                           break;
                   }
           break;
           case WM_USER:
                   {  // Show synchronization activity.
                      TCHAR szBuffer[101];
                      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 ) );
                      if ( row > 200 )
                         row = 0;
                      else
                         row += 20;
                      ReleaseDC( hWnd, hDC );
                   }
                   break;
           case WM_DESTROY: // Get back resources from critical section
object.
                   DeleteCriticalSection(&cs);
                   PostQuitMessage( 0 );
                   break;
           default:
                return DefWindowProc( hWnd, uMsg, wParam, lParam );
   }
   return NULL;
}