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



Pdf көрінісі
бет188/220
Дата25.02.2022
өлшемі2,22 Mb.
#26438
түріОқулық
1   ...   184   185   186   187   188   189   190   191   ...   220
Байланысты:
қазақша кітап

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   ...   184   185   186   187   188   189   190   191   ...   220




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

    Басты бет