Esempio utilizzo Thread e Mutex
#include <stdio.h>
#include <process.h>
#include <windows.h>
#include <conio.h>
/*
Creiamo 2 thread somma e sottrai, che condividono la risorsa numero e che corrispettivamente aggiungono e
sottraggono 1 al valore corrente di numero.
*/
DWORD somma
(LPDWORD b
);
//Thread per sommare 1 al valore di numero
DWORD sottrai
(LPDWORD b
);
//Thread per sottrarre 1 al valore di numero
DWORD finito
(LPDWORD b
);
//Thread per gestire la fine del processo
LPCWSTR mutexName =
(LPCWSTR
)"mutexNUM";
//Funzione principale
void main
()
{int numero=
0,fine=
0;
HANDLE hmutexNUM;
//Handle per gestire il mutex per l'unica risorsa condivisa
HANDLE hThreadSomma,hThreadFine,hThreadSottrai;
//Handles per gestire i 3 thread
DWORD dwThreadIdFinito,dwThreadIdSomma,dwThreadIdSottrai;
//Per gestire l'id dei Threads
/*
HANDLE CreateMutex(
LPSECURITY_ATTRIBUTES lpMutexAttributes,
// Puntatore alle impostazioni di sicurezza (solitamente posto a NULL)
BOOL bInitialOwner, // Specifica il proprietario del Mutex, se TRUE il processo chiamante è il proprietario
LPCTSTR lpName // Nome del mutex (tra virgolette)
);
*/
hmutexNUM=CreateMutex
(NULL,
TRUE, mutexName
);
//crea il mutex
if (hmutexNUM==
NULL) //controlla se la creazione è avvenuta con successo
printf("errore creazione mutex");
/*
HANDLE CreateThread(
LPSECURITY_ATTRIBUTES lpThreadAttributes, // Puntatore alle impostazioni di sicurezza (solitamente posto a NULL)
DWORD dwStackSize, // Grandezza iniziale dello stack (solitamente posto a 0)
LPTHREAD_START_ROUTINE lpStartAddress, // Richiama la funzione con il tipo LPTHREAD_START_ROUTINE
LPVOID lpParameter, // Parametri della funzione
DWORD dwCreationFlags, // Flag di creazione.Se 0 il thread viene creato immediatamente
//Se CREATE_SUSPENDED viene creato in modalità sospesa
//(da riattivare con ResumeThread)
LPDWORD lpThreadId // Puntatore che riceverà l'id del Thread
);
*/
//CREAZIONE THREAD
hThreadFine=CreateThread
(NULL,
0,
(LPTHREAD_START_ROUTINE
) finito,
(LPVOID
) &fine,
0,&dwThreadIdFinito
);
hThreadSomma=CreateThread
(NULL,
0,
(LPTHREAD_START_ROUTINE
) somma,
(LPVOID
) &numero,CREATE_SUSPENDED,&dwThreadIdSomma
);
hThreadSottrai=CreateThread
(NULL,
0,
(LPTHREAD_START_ROUTINE
) sottrai,
(LPVOID
) &numero,CREATE_SUSPENDED,&dwThreadIdSottrai
);
//Settiamo priorità diverse ai Thread
SetThreadPriority
(hThreadSomma,THREAD_PRIORITY_NORMAL
);
SetThreadPriority
(hThreadSottrai,THREAD_PRIORITY_NORMAL
);
//Controlla se la creazione è avvenuta con successo
if (hThreadFine==
NULL || hThreadSomma==
NULL || hThreadSottrai==
NULL)
printf("Creazione Thread fallita");
else
{
//Attiva i Thread precedentemente creati in modalità sospesa
ResumeThread
(hThreadSomma
);
ResumeThread
(hThreadSottrai
);
while (fine==
0);
//Attesa attiva (aspetta che fine viene posto ad 1 (tramite input tastiera)
//Termina i Thread con valore di uscita 0.
TerminateThread
(hThreadSottrai,
0);
TerminateThread
(hThreadSomma,
0);
TerminateThread
(hThreadFine,
0);
}
}
DWORD somma
(LPDWORD b
)
{
HANDLE hmutex;
int *num,fine=
0;
num=
(int *
) b;
//Creazione variabile di tipo Handle per la gestione del Mutex
/*
HANDLE OpenMutex(
DWORD dwDesiredAccess, // Flag di accesso
Se MUTEX_ALL_ACCESS Permette tutti i tipi di accesso
Se SYNCHRONIZE Permette al mutex di usare funzioni di Wait e Release
BOOL bInheritHandle, // Indica se il Mutex è ereditabile (TRUE/FALSE)
LPCTSTR lpName // Nome del Mutex da aprire
);
*/
hmutex=OpenMutex
(EVENT_MODIFY_STATE|SYNCHRONIZE,
FALSE, mutexName
);
while (fine==
0)
{
WaitForSingleObject
(hmutex,INFINITE
);
(*num
)++;
printf("Somma: %d\n",*num
);
ReleaseMutex
(hmutex
);
//rilascia il mutex
Sleep
(50);
}
return 0;
}
DWORD sottrai
(LPDWORD b
)
{
HANDLE hmutex;
int *num,fine=
0;
num=
(int *
) b;
hmutex=OpenMutex
(EVENT_MODIFY_STATE|SYNCHRONIZE,
FALSE, mutexName
);
while (fine==
0)
{
WaitForSingleObject
(hmutex,INFINITE
);
(*num
)--;
printf("Sottrai: %d\n",*num
);
ReleaseMutex
(hmutex
);
Sleep
(50);
}
return 0;
}
DWORD finito
(LPDWORD b
)
/*
Quando l'utente digita un qualunque carattere da tastiera, pone fine = 1
Implicando l'interruzione del processo (in particolare dei Threads)
*/
{
int *fine;
fine=
(int *
) b;
_getch
();
*fine=
1;
return 0;
}
Torna alla pagina della materia
Non ci sono commenti in questa pagina. [Scrivi commento]