Оқулық «Федералдық білім беруді дамыту институты»



Pdf көрінісі
бет136/158
Дата01.07.2023
өлшемі3.83 Mb.
#475485
түріОқулық
1   ...   132   133   134   135   136   137   138   139   ...   158
операциялық жуйелер

SemaphoreAndMutex.c
#include 
#include 
#include 
DWORD WINAPI ThreadProc(LPVOID lpParam); 
void ErrorReport(LPTSTR lpszFunction);
int main()
{
DWORD dwThreadId;
HANDLE hThread, hSem, hMutex; 
unsigned i;
// сигналды емес бастамамен семафор құрамыз
// мьютексті құруда процестерді синхрондау үшін
// осы семафор қолданылады if((hSem =
CreateSemaphore(NULL, 0, 1, "Threadl")) == NULL)
{
ErrorReport(TEXT("CreateSemaphore()")); return(1);
}


254 
hThread = CreateThread(
NULL, 
// әдеттегідей құқық // әдепкә 
бойынша қамшы өлшемі 
ThreadProc, // ағым функциясы 
NULL, 
// функция үшін аргумент жоқ
0, 
// әдеттегідей жалаушалар
&dwThreadId); 
if(hThread == NULL)
{
ErrorReport(TEXT("CreateThread()")); 
return(1);
}
// мьютексті еншілес етіп құру
// есептеуіш ағымымен WaitForSingleObject(hSem, 
INFINITE);
// мьютекс құруда дескриптор аламыз if((hMutex = 
OpenMutex(MUTEX_ALL_ACCESS, FALSE, "Thread2")) == 
NULL)
{
ErrorReport(TEXT("OpenMutex()")); 
return(1);
}
// алғашқы ағымның негізгі циклі for(i = 0; i < 10; 
++i)
{
// басқару жіберілімін күту
// туындаған ағымнан 
WaitForSingleObject(hMutex, INFINITE);
// ақпараттарды консолды 
шығару printf("p%d ", i);
// алғашқы ағымды 1 сек блоктау Sleep(1000);
// туындаған ағымның басқарылуын жіберу 
ReleaseMutex(hMutex);
}
// туындаған ағымның аяқталуын күту 
WaitForSingleObject(hThread, INFINITE);
// дескриптор жабу CloseHandle(hThread);
// семафор және мьютекстің дескрипторын жабу 
CloseHandle(hSem);
CloseHandle(hMutex);


255 
printf("\n");
return(0);
}
DWORD WINAPI ThreadProc(LPVOID lpParam)
{
HANDLE hSem, hMutex; unsigned i;
// ертерек семафорын дескриптор алу if((hSem = 
OpenSemaphore(SEMAPHORE_ALL_ACCESS, FALSE, 
"Thread1")) == NULL)
{
ErrorReport(TEXT("OpenSemaphore()")); return(1);
}
// бастапқы сигналды емес мьютексті құру
// 
if((hMutex =CreateMutex(NULL, FALSE, "Thread2")) == 
NULL)
{
ErrorReport(TEXT("CreateMutex()")); 
return(1);
}
// семафорды сигналды күйге ауыстыру
// ақпаратты шығаруды синхрондау үшін мьютексты 
құрылуы туралы алғашқы ағымына хабарлау
// ReleaseSemaphore(hSem, 1, NULL); 
// еншілес ағымның негізгі циклі
for(i = 0; i < 10; ++i)
{
// бастапқы ағымның басқаруды жіберуін күту
//
WaitForSingleObject(hMutex, INFINITE);
// ақпараттарды консолға шығару
printf("c%d ", i);
// ағымды 4 секундқа 
блоктауSleep(4000);
// алғашқы ағымға басқаруды жібереміз 
ReleaseMutex(hMutex);
}
// семафор мен мьютекстің дескрипторын жабамыз 
CloseHandle(hSem);


256 
CloseHandle(hMutex); return(0);
}
void ErrorReport(LPTSTR lpszFunction)
{
LPVOID lpMsgBuf;
LPVOID lpDisplayBuf;
DWORD dw = GetLastError();
FormatMessage(
FORMAT_MESSAGE_ALLOCATE_BUFFER | 
FORMAT_MESSAGE_FROM_SYSTEM,
NULL,
dw,
MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), (LPTSTR) 
&lpMsgBuf,
0, NULL );
lpDisplayBuf = (LPVOID)LocalAlloc(LMEM_ZEROINIT, 
(lstrlen((LPCTSTR)lpMsgBuf)+lstrlen((LPCTSTR) 
lpszFunction)+40)*sizeof(TCHAR)); 
_stprintf((LPTSTR)lpDisplayBuf,
TEXT("%s failed with error %d: %s"), lpszFunction, 
dw, lpMsgBuf);
MessageBox(NULL, (LPCTSTR)lpDisplayBuf, 
TEXT("Error"), MB_OK);
LocalFree(lpMsgBuf);
LocalFree(lpDisplayBuf);
}
Берілген үлгіде семафор тек процестердің алғашқы синхрондау 
үшін қолданылады. Семафордың көмегімен, еншілес ағым алғашқы 
ағымға мьютекстің құрылуын хабарлайды, ол алғашқы және еншілес 
есептеуіш ағымдарды консолға қол жеткізуін болдырмауды 
ұйымдастырады. Ары қарай семафор қолданылмайды, тек мьютекс 
қолданылады.
Берілген бағдарламаның жұмысы нәтижесінде консолға келесі жол 
шығады: 
c0 p0 cl pi c2 p2 c3 p3 c4 p4 c5 p5 c6 p6 c7 p7 c8 p8 c9 
р9


257 
Алдындағыдай, екі ағым үйлестірілген және олардың шығуы қатаң 
кезектеседі. Егер де жоғарыда келтірілген бағдарламаға ResetMutex() 
және WaitForSingleObjectQ функцияларының шақыртуларында ішкі 
циклдері және бастапқы ағым, ағым тобын түсіндіре кетсек, 
бағдарлама жұмысының нәтижесі мынадай болады: 
c0 p0 pl p2 p3 cl p4 p5 p6 p7 p8 c2 p9 c3 c4 c5 c6 c7 c8 
c9
Мұнда тағы жағдай қайталанады, ағымдардың синхрондауы 
жүргізілмесе бастапқы ағым өзінің жұмысын еншілес ағымнан бұрын 
аяқтайды және консолға ақпараттарды шығарғанда екі есептеуіш 
ағымдар синхрондалмайды.


Достарыңызбен бөлісу:
1   ...   132   133   134   135   136   137   138   139   ...   158




©dereksiz.org 2024
әкімшілігінің қараңыз

    Басты бет