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



Pdf көрінісі
бет190/220
Дата25.02.2022
өлшемі2,22 Mb.
#26438
түріОқулық
1   ...   186   187   188   189   190   191   192   193   ...   220
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   ...   186   187   188   189   190   191   192   193   ...   220




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

    Басты бет