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



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

ProcessAndThread.c:
 
#include 
#include 
#include 
// құрылатын ағымға берілетін ақпараттар 
typedef struct _Data {
TCHAR cmd[20];
int parentThreadID;
} TDATA, *PTDATA;
DWORD WINAPI ThreadProc(LPVOID lpParam);
void ErrorReport(LPTSTRlpszFunction);
int main()
{
PTDATA pData;
DWORD dwThreadId;
HANDLE hThread;
// құрылатын ағымға берілетін ақпараттар жадын 
белгілейміз
pData = (PTDATA)HeapAlloc(GetProcessHeap(), 
HEAP_ZERO_MEMORY, sizeof(TDATA));


239 
NULL,
0,
if(pData == NULL)
{
ErrorReport(TEXT("HeapAlloc()"));
return(1);
}
// ақпараттар құрылымын толтырамыз: шығаратын команда 
// айнымалы шеңберлер және қазіргі ағымның 
идентификаторы
// ағымда
_tcscpy(pData->cmd, TEXT("cmd /c set ComSpec")); 
pData->parentThreadID = GetCurrentThreadId();
// жаңа ағым құрамыз
hThread = CreateThread(
// әдеттегідей қауіпсіздік атрибуттары 
// әдеттегідей ағым қамшысының өлшемі
ThreadProc,// pData ағымының негізгі функциялары,
//ағымға арналған ақпарат
// әдеттегідей ағым құрудың жалауы 
&dwThreadId); // идентификаторын құрайды
// құрылған ағымның
// ағымның сәтті құрылғанын тексереміз
if (hThread == NULL)
{
ErrorReport(TEXT("CreateThread()"));
return(1);
}
// тайм-аутсыз ағымның аяқталуын күтеміз 
WaitForSingleObject(hThread, INFINITE);
// CloseHandle(hThread) ағымының дескрипторын 
жабамыз;
return(0);
}
// DWORD WINAPI ThreadProc(LPVOID lpParam)құрылатын 
ағымның басты функциясы
{
STARTUPINFO si;
PROCESS_INFORMATION pi;
PTDATA pData;
// pData = (PTDATA)lpParam құрылатын ағымына 
жіберілетін ақпаратты аламыз;
// аталық-процесс туралы ақпараттың консолын аламыз 


240 
// туындайтын процесс туралы ақпараттың консолын 
аламыз
// құрылған ағым
_tprintf (TEXT("New thread is created by thread with 
Id %d and command to execute is \"%s\"\n"),
pData->parentThreadID, pData->cmd);
ZeroMemory(&si, sizeof(si));
si.cb = sizeof(si);
ZeroMemory(&pi, sizeof(pi));
// процесс-тобын қосамыз
if(!CreateProcess(NULL,// бірінші параметрді аламыз
// 
pData->cmd, 
// Командалық жол 
NULL,
// мұраланатын құрылатын
//процесс дескрипторы
// Дескриптор первичного
//
FALSE, // мұраланбайтын ағым,
// Процесс дескрипторы аталық
// процестен мұраланбайды
0, 
// 
NULL // әдеттегідей процесс құру жалауы,
NULL // аталық – процесінен
// шеңбер мұраланады
// қазіргі каталог
//аталық процестен мұраланады
&si, // бастапқы қондырғыға нұсқау
// процестер үшін
&pi) // процестен және алғашқы ағым 
дескрипторын аламыз 
)
{
ErrorReport(TEXT("CreateProcess()"));
return(1);
}
// процесс тобы орындалуының аяқталуын күтеміз // 
тайм-аутсыз
WaitForSingleObject(pi.hProcess, INFINITE);
// процесс дескрипторын және оның алғашқы ағымын 


241 
жабамыз // 
CloseHandle(pi.hProcess);
CloseHandle(pi.hThread);
// ағым параметрлерге белгіленген жадыны босатамыз 
HeapFree(GetProcessHeap(), 0, pData); 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);
}
Берілген бағдарламамен жұмыс процесінде, екі параметрді 
қабылдайтын: командадан, аталық ағымның идентификаторы мен 
жолдан тұратын тағы бір ағым құрылады. Өз кезегінде, құрылған ағым, 
өзіне берілген команданы (қарау командасының мысалында, 
айнымалы шеңбердің мәндері ComSpec — «cmd /c set ComSpec») 
қолдана отырып, жаңа процесс туындатады.
Жоғарыда келтірілген бағдарлама жұмысының нәтижесінде 
консолға хабарлама шығады: 


242 
C:\>ProcessAndThread.exe
New thread is created by thread with Id 3136 and 
command to execute is "cmd /c set ComSpec" 
ComSpec=C:\WIN\system32\cmd.exe
C:\>
Берілген мысалда қарастырылған, тағы бір функция қатарын еске 
салған жөн. Алдымен, ол WaitForSingleObjectQ функциясы:
include 
DWORD WINAPI WaitForSingleObject(
HANDLE hHandle,
DWORD dwMilliseconds);
Бұл функция қазіргі процесте жіберілген hHandle дескрипторына 
ұқсатылған обьект, сигналды күйге енбегенше немесе берілген 
dwMilliseconds күту кезеңі милисекундта өтуіне дейін блоктайды. Егер 
dwMilli- seconds параметрі INFINITE мәніне ие болса, онда күту кезеңі 
өтіп кетпейді және процесс, берілген обьектінің сигналды күйге өтуі 
кезінде оянады. WaitForObjects() тобының функциялары, Windows 
тобының операциялық жүйелерімен сүйемелденетін синхрондауші 
механизмдер элементінің бірі болып табылады.
Берілген функцияның күйлерін бақылай алатын обьектілер ретінде, 
оқиғалар, мьютекстер, процесстер, семафорлар, ағымдар және т.б. 
қатыса алады. Егер обьектілер, процестер немесе ағымдар 
бақыланатын болса, онда олар үшін сигналды күй олардың 
аяқталғанында түседі. 
Егер функция, бақыланатын обьектілердің сигналды күйге өтуі 
кезінде аяқталса, онда WAIT_ OBJECT_0 мәні қайтарылады. Егер де 
функция күту кезеңінің өтуімен аяқталса, онда WAIT_TIMEOUT мәні 
қайтарылады.
Егер бір уақытта бірнеше обьектілерді бақылау қажет болса, онда 
WaitForMultipleObjectsQ функциясы қолданылады. 
DWORD WINAPI WaitForMultipleObjects(
DWORD nCount,
const HANDLE* lpHandles,
BOOL bWaitAll,
DWORD dwMilliseconds);


243 
Бұл функцияда nCount параметрі, обьектілер дескрипторы жалпы 
санын анықтайды. LpHandles параметрінде обьектілер дескрипто-
рының алабы беріледі, олардың күйі WaitForMultipleObjects() 
функциясымен бақыланады. Егер bWaitAll параметрі үшін TRUE мәні 
қондырылса, онда функция күтілу процесін басқаруды, алаптағы 
барлық обьектілерді сигналды күйге ауыстыруға ауыстырғаннан кейін 
қайтарады. Қарсы жағдайда, функция барлығын бір уақытта емес бір 
обьектінің сигналды күйге ауысуын күтеді. DwMilliseconds параметрі, 
WaitForSingleObject() функциясы сияқты, обьектілерді сигналды күйге 
ауыстыруының күтілуі кезеңін беру үшін оның бітуінен, басқару 
процессі функциясының шақыртылуымен қайтарылады. Бұл жағдай, 
егерде күтілу кезеңі біткенде және обьектінің бірі де сигналдық күйге 
ауыспаса да жүреді. Бұл параметр сондай-ақ INFINITE мәнін қабылдай 
алады.
Жұмыс аяқталғаннан соң, бұл функция, егер обьектілердің 
сигналды күйге ауысуы күтілуінің уақыты өтсе, WAIT_TIMEOUT 
мәнін қайтарады. Егер функцияларды шақырту кезінде bWaitAll 
параметрі TRUE тең болса және барлық обьектілер күту кезеңінің 
өтуіне дейін ауыстырылу керек болса, функция WAIT_OBJECT_0 
мәнін қайтарады. Егер де bWaitAll параметрі FALSE тең болса және 
қандай да бір обьект сигналды күйүге ауыстырылса, WAIT_OBJECT_0 
+ n мәні қайтарылады, мұнда n —сигналды күйге ауыстырылған, 
lpHandles алабындағы обьектінің нөмірі.
Дескрипторлары ашылатын, обьектілермен жұмысты аяқтаған соң, 
соңғылары жабылуы керек. Ол үшін CloseHandle() функциясы 
қолданылады:
include 
DWORD WINAPI BOOL CloseHandle(HANDLE hObject);
Параметр ретінде ертерек ашылған дескриптор беріледі. Процестің 
дескрипторлары және ағымдар, егер процестің өздері де, ағымдар да 
аяқталған соң ғана жабылуы тиіс.


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




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

    Басты бет