problema Semafor de sincronizarea accesului la resurse partajate

Scurtă descriere a programului:

Sub Introduceți numărul de fire - va fi ca o serie de resurse partajate. Fluxul poate fi rulat în afara ferestrei programului prin apăsarea butonului, dar, în cazul în care în acel moment fără curgere liberă a unei cantități predeterminate nu este, atunci stația de operare pentru a elibera semaforul.

Subiectele afectate: crearea proceselor, crearea unei organizații de acces simultan la resursele partajate semaforului (în cazul în care există mai multe resurse similare și accesul necesare pentru oricare dintre ele), așteptați-funcții care trimit mesaje din fluxul.

O descriere a funcțiilor:

Această funcție creează sau se deschide un semafor. Acesta poate fi numit sau nenumit, în funcție de necesități.

HANDLE CreateSemaphore (
LPSECURITY_ATTRIBUTES lpSemaphoreAttributes, // Atribute de protecție
LONG lInitialCount, // Numarul de resurse gratuite la inițializarea
lMaximumCount LONG, // Total resurse
Nume LPCTSTR lpName //
);

typedef struct _SECURITY_ATTRIBUTES <
DWORD nLungimea; // dimensiune structura (de obicei luate sizeof)
LPVOID lpSecurityDescriptor; // pointer la un mâner care controlează articulația
// utilizarea instalației
BOOL bInheritHandle; // pavilion pentru a permite procesul de copil obiect moștenind
> SECURITY_ATTRIBUTES, * PSECURITY_ATTRIBUTES;

lInitialCount - Acesta este numărul de resurse disponibile pentru a crea un semafor. Dacă setați acest parametru 0, starea inițială a semaforului este non-semnalat, și anume așteptați-funcția se va opri debitul până când semaforul va semnala statului.
lMaximumCount - Aceasta specifică distribuirea cât de multe resurse avem nevoie pentru a monitoriza. Parametrul IInitialCount nu mozhut depășește numărul specificat aici.

Mai multe informații sunt disponibile pe MSDN.

Așa cum este utilizat în acest program:

GetDlgItemText (IDC_EDIT1, strThreads); // obține numărul de fire
m_iCount = atoi (strThreads); // se păstrează într-o variabilă membru al clasei
// (nu uitați să-l declare în h-fișier
m_hSemaphore = CreateSemaphore (NULL, m_iCount, m_iCount, NULL); // Crearea semafoarelor pentru suma noastră de resurse

Această funcție suspendă execuția fluxului de curent, atâta timp cât parametrii menționați în kernel-ul său nu vine la starea de semnal de obiect (de asemenea, de ieșire prin timeout). Ograninicheniya utilizate pentru accesul la resursele partajate. Parametrul este adesea un eveniment, semafor, sau mutex, dar, de asemenea, ca un parametru poate fi o notificare (notificare), fluxul de proces și alte câteva obiecte. Valoarea returnată indică faptul că a fost ieșirea din funcție. Acest lucru poate fi WAIT_ABANDONED (valoare specifică returnată în cazul în care fluxul este complet, care deține un mutex), WAIT_OBJECT_0 (obiect a fost semnalat - în acest caz, funcția se pune ea însăși într-un semafor care nu a semnalat, și crește numărul contor de resurse ocupate), WAIT_TIMEOUT (funcția de timeout).

DWORD WaitForSingleObject (
MÂNER hHandle, // Manevrați la obiectul nucleu semnalat că ne interesează
dwMilliseconds DWORD // timeout, după care ar putea întrerupe în așteptare
);

Să luăm în considerare câteva dintre parametrii funcției:
dwMilliseconds - Aici puteți specifica orice moment dorit afară, în plus, dacă specificați 0, funcția returnează fluxul de comandă imediat (astfel încât să puteți verifica starea obiectului), iar dacă specificați constantă INFINIT. Funcția nu ia în considerare timpul și așteptați numai starea de semnal a nucleului obiectului.

Mai multe informații sunt disponibile pe MSDN.

Așa cum este utilizat în acest program:

WaitForSingleObject (m_hSemaphore, INFINITE); // Prin apăsarea butonului așteptați până când semaforul
// nu va fi liber (adică, până când cel puțin una dintre resursele nu sunt disponibile)
int iRecourceID = 0;
pentru (int i = 0; i // (valoare element de matrice adecvat să fie 0)
if (m_pBusyResources [i] == 0)
m_pBusyResources [iRecourceID] = 1; // Marcați resursa ca ocupat

Această caracteristică vă permite să-i spuneți semafoarelor să elibereze una sau mai multe resurse. Valoarea returnată este o operațiune de succes.

BOOL ReleaseSemaphore (
MÂNER hSemaphore, // Manevrați la semaforul
lReleaseCount LONG, // număr de resurse eliberate
LPLONG lpPreviousCount // Valoarea anterioară a contorului semaforului
);

Să luăm în considerare câteva dintre parametrii funcției:
lpPreviousCount - opțiunea rambursabilă, în cazul în care puteți obține valoarea contorului semaforului la funcția de acțiune. Dacă este necesar, aceste informații nu sunt disponibile, peredaom NULL.

Mai multe informații sunt disponibile pe MSDN.

Așa cum este utilizat în acest program:

DWORD WinAPI WorkThread (void * pParam) // flux de lucru
Sleep (5000); // „Adormi“
PostMessage (g_hWnd, WM_FINISH, (wParam) pParam, 0);
// Trimite un mesaj despre finalizarea fluxului
ReleaseSemaphore (m_hSemaphore, 1, NULL); // Eliberați semaforul
return 0;
>

Să luăm în considerare câteva dintre parametrii funcției:
lpStartAddress - indicatorul pentru a porni funcția de curgere (de exemplu, numele său), care trebuie să fie declarate în cadrul aplicației. Acesta ar trebui să aibă un anumit tip:

DWORD WinAPI ThreadProc (// nume de funcție poate fi arbitrară
LPVOID lpParameter
);

lpParameter - parametru a trecut la funcția de flux de pornire. În cazul în care un fir trebuie să treacă mai mulți parametri, trebuie fie să utilizați variabile globale, sau să declare o structură cu toate datele necesare și îl transmite.
dwCreationFlags - în general, acest parametru este utilizat pentru a indica dacă pentru a începe fluxul imediat după crearea sau asupra funcției de apel ResumeThread (în primul caz, parametrul de transmisie poate fi 0, în al doilea - CREATE_SUSPENDED pavilion).
lpThreadId - parametru de retur - id flux care poate fi uneori utilă (de exemplu, dacă un mesaj va fi trimis în amonte). În cazul în care nu este nevoie de ID-ul, puteți transmite NULL.

Mai multe informații sunt disponibile pe MSDN.

Așa cum este utilizat în acest program:

CloseHandle (CreateThread (NULL, 0, WorkThread, (void *) iRecourceID, 0, dwID)); // Crearea unui flux și imediat apropiat descriptor ea, pentru că nu avem nevoie

Funcția trimite o fereastră de mesaj specificat asincronă, și anume returnează imediat (fără a aștepta un mesaj pentru a fi prelucrate). La fereastra, care trimite un mesaj pentru a fi handler adecvat, și identificatorul de mesaj trebuie să fie declarate în program.

BOOL PostMessage (
HWND hWnd, // fereastra HWND
UINT Msg, // Mesaj ID
WParam wParam, // parametru a trecut la handler
Parametrul lParam lParam // a trecut la handler
);

Să luăm în considerare câteva dintre parametrii funcției:
hWnd - fereastra HWND care trimite un mesaj. Această valoare poate fi somnolență din clasa ferestrei - acesta este stocat în câmpul m_hWnd.
Msg - un identificator de mesaj dacă mesajul utilizatorul, este necesar să se declare ID-ul utilizând directiva defini (valoarea trebuie să înceapă cu WM_USER).
wParam, lParam - parametrii care urmează să fie trecut la funcția de tratare a mesajului. În general, puteți adăuga propriul mesaj în harta de mesaje și asocia un anumit tip de funcții handler:

LRESULT MessageProc (
WParam wParam,
lParam lParam
);

Mai multe informații sunt disponibile pe MSDN.

Așa cum este utilizat în acest program:

#define WM_FINISH (WM_USER + 1)
//.
BEGIN_MESSAGE_MAP (CPrioritiesDlg, CDialog)
//.
ON_MESSAGE (WM_FINISH, OnThreadFinish) // Adauga un mesaj în harta mesaj
END_MESSAGE_MAP ()
//.
PostMessage (g_hWnd, WM_FINISH, (wParam) iCounter (lParam) GetThreadPriority (GetCurrentThread ()));
//.
LRESULT CPrioritiesDlg :: OnThreadFinish (wParam wParam, lParam lParam)
// mesaje handler de funcții (declarat în clasa ferestrei în h-file)
//.
return 0;
>