МІНІСТЕРСТВО ОСВІТИ І НАУКИ УКРАЇНИ
НАЦІОНАЛЬНИЙ УНІВЕРСИТЕТ “ЛЬВІВСЬКА ПОЛІТЕХНІКА”
Кафедра ЕОМ
Звіт
до лабораторної роботи № 1
з дисципліни
" Системне програмування "
на тему: «Процеси та потоки»
Мета: Засвоїти поняття «процесів» та «потоків» як основних компонентів сучасних операційних систем. Здобути навики створення, керування та знищення «процесів» та «потоків» в операційній системі Windows.
Варіант 2
Розробити програму в середовищі Visual Studio, що демонструє використання системних викликів, відзначених символом “+”, відповідно до варіанту (таблиця 4).
Написати функцію потоку, яка як вхідний параметр приймає дескриптор відкритого текстового файлу. Функція повинна здійснювати посимвольне виведення у файл номер процесу, номер потоку та системний час. Передбачити достатню кількість ітерації запису в файл з одної функції потоку. Відкриття файлу слід виконувати до створення потоку, використовуючи функцію FileOpen(), а після завершення роботи з файлом слід викликати функцію FileClose().
Щоб продемонструвати паралельне виконання створеного потоку з первинним потоком процесу, в цикл запису з файлу потрібно додати виклик Sleep(Num), де Num – час в мілісекундах, на яке слід призупинити виконання потоку. Затримку також можна організувати за допомогою лічильника до якогось досить великого числа.
Код програми
#include "func.h"
HANDLE hndl = GetStdHandle(STD_OUTPUT_HANDLE);
void ProcessExample(){
SetConsoleTextAttribute(hndl, FOREGROUND_GREEN);
printf("~~~~~~~~~~ Process Example ~~~~~~~~~~~\n");
SetConsoleTextAttribute(hndl, FOREGROUND_INTENSITY);
printf("ShellExecute");
HINSTANCE hInst = (HINSTANCE)ShellExecuteA(0, "open", "C:\\Windows\\write.exe", "C:\\example.txt", 0, SW_SHOW);
if ((int)hInst < 31)
printf(" failed\n");
else
SetConsoleTextAttribute(hndl, FOREGROUND_BLUE);
printf(" ok\n");
SetConsoleTextAttribute(hndl, FOREGROUND_INTENSITY);
printf("CreateProcess paint");
STARTUPINFO si;
PROCESS_INFORMATION pi;
DWORD code;
ZeroMemory(&pi, sizeof(pi));
ZeroMemory(&si, sizeof(si));
si.cb = sizeof(si);
if (!CreateProcess
(L"c:\\windows\\system32\\mspaint.exe", NULL, NULL, NULL, FALSE, NORMAL_PRIORITY_CLASS, NULL, NULL, &si, &pi)
)
printf(" failed\n");
else
SetConsoleTextAttribute(hndl, FOREGROUND_BLUE);
printf(" ok\n");
SetConsoleTextAttribute(hndl, FOREGROUND_INTENSITY);
printf("OpenProcess");
HANDLE hMyProc = OpenProcess(PROCESS_ALL_ACCESS, 0, pi.dwProcessId);
if (hMyProc == INVALID_HANDLE_VALUE)
printf(" failed\n");
else
SetConsoleTextAttribute(hndl, FOREGROUND_BLUE);
printf(" ok\n");
SetConsoleTextAttribute(hndl, FOREGROUND_INTENSITY);
printf("GetExitCodeProcess");
if (!(GetExitCodeProcess(pi.hProcess, &code))) {
printf("GetExitCodeProcess() failed: %d\n", GetLastError());
}
else
SetConsoleTextAttribute(hndl, FOREGROUND_BLUE);
printf(" ok %d \n", code);
TerminateProcess(pi.hProcess, 0);
SetConsoleTextAttribute(hndl, FOREGROUND_INTENSITY);
printf("TerminateProcess ");
SetConsoleTextAttribute(hndl, FOREGROUND_BLUE);
printf("ok");
SetConsoleTextAttribute(hndl, FOREGROUND_INTENSITY);
printf("SetPriorityClass to idle");
if (SetPriorityClass(hMyProc, IDLE_PRIORITY_CLASS)){
SetConsoleTextAttribute(hndl, FOREGROUND_BLUE);
printf(" ok\n");
}
else
printf(" failed\n");
CloseHandle(pi.hProcess);
CloseHandle(pi.hThread);
}
static unsigned _stdcall ThreadFunc(void* File)
{
HANDLE hFile = File;
DWORD WrittenBytes;
while (1)
{
WriteFile(hFile, "+", 1, &WrittenBytes, 0);
}
return 0;
}
void ThreadExample()
{
SetConsoleTextAttribute(hndl, FOREGROUND_GREEN);
printf("~~~~~~~~~~~~Thread Example~~~~~~~~~~~~\n");
unsigned ThreadId;
LPDWORD ThreadExCode = new DWORD;
HANDLE hMyThread;
HFILE hFile;
DWORD WrittenBytes;
hFile = (HFILE)CreateFile(L"D:\\nlab1.txt", GENERIC_READ | GENERIC_WRITE, FILE_SHARE_READ | FILE_SHARE_WRITE,
NULL, CREATE_NEW, FILE_ATTRIBUTE_NORMAL, 0);
SetConsoleTextAttribute(hndl, FOREGROUND_INTENSITY);
printf("_beginthreadex ");
hMyThread = (HANDLE)_beginthreadex(NULL, 0, ThreadFunc, (void *)hFile, 0, &ThreadId);
if (hMyThread == INVALID_HANDLE_VALUE)
printf(" failed\n");
else
{
SetConsoleTextAttribute(hndl, FOREGROUND_BLUE);
printf(" ok\n");
SetConsoleTextAttribute(hndl, FOREGROUND_INTENSITY);
printf("GetThreadPriority %d\n", GetThreadPriority(hMyThread));
SetConsoleTextAttribute(hndl, FOREGROUND_INTENSITY);
printf("SetThreadPriority");
if (SetThreadPriority(hMyThread, THREAD_PRIORITY_ABOVE_NORMAL)){
SetConsoleTextAttribute(hndl, FOREGROUND_BLUE);
printf(" ok\n");
}
else
printf(" failed\n");
SetConsoleTextAttribute(hndl, FOREGROUND_INTENSITY);
printf("GetThreadPriority %d\n", GetThreadPriority(hMyThread));
SetConsoleTextAttribute(hndl, FOREGROUND_RED);
printf("Waiting for thread finishing \n");
int i = 0;
while (i < 1000)
{
i++;
WriteFile((void*)hFile, "*", 1, &WrittenBytes, 0);
GetExitCodeThread(hMyThread, ThreadExCode);
if (*ThreadExCode != STILL_ACTIVE)
{
_endthreadex(0);
// TerminateThread(hMyThread, 0);
}
}
TerminateThread(hMyThread, 0);
//_endthreadex(0);
SetConsoleTextAttribute(hndl, FOREGROUND_INTENSITY);
printf("_endthreadex ");
SetConsoleTextAttribute(hndl, FOREGROUND_BLUE);
printf("ok");
}
}
Результат виконання програми під час демонстрації:
Рис.1. Відкриття програми в консолі
Рис.2. Демонстрація роботи процесу «ShellExecute»
Рис.3. Демонстрація роботи процесу «CreateProcess paint»
Рис.4. Демонстрація запису в файл з одної функції потоку
Висновок: Після виконання даної лабораторної роботи я засвоїла поняття «процесів» та «потоків» як основних компонентів сучасних операційних систем. Здобула навики створення, керування та знищення «процесів» та «потоків» в операційній системі Windows.