Министерство образования и науки, молодежи и спорта Украины
Севастопольский национальный технический университет
Кафедра
Информационных
систем
ЛАБОРАТОРНАЯ РАБОТА №2
«Использование программного интерфейса Win32 API.
Процессы и потоки в ОС Windows.»
Выполнила:
Ст.гр. И-31д
Юрченко Н.А.
Проверил:
Шишкевич В.Е.
Севастополь
2011
1. Цель работы
Изучение возможности использования программного интерфейса приложений(API) операционных систем Windows 95-2000, NT. Приобретение практических навыков создания и управления процессами и потоками, используя Win32 API в средах программирования Borland Delphi и C++ Builder.
2. Постановка задачи
Написать программу Sort, реализующую следующий алгоритм:
Зафиксировать время начала Tstrt выполнения программы.
Вывести на экран время Tstrt в формате: минуты:секунды:миллисекунды;
Зафиксировать текущий момент времени t1;
Для i от 1 до 100(количество повторений может быть изменено в зависимости от быстродействия процессора) повторять:
Заполнить массив целых чисел случайными значениями из диапазона 0-10000;
Отсортировать массив;
Зафиксировать текущий момент времени t2;
Определить среднее время одной сортировки: (t2-t1)/100;
Вывести на экран среднее время одной сортировки(в миллисекундах);
Зафиксировать время окончания Tend выполнения программы;
Вывести на экран время Tend в формате: минуты:секунды: миллисекунды;
Язык программирования, метод и направление сортировки, а также количество элементов массива N выбирается в соответствии с вариантом задания.
Написать программу Master, выполняющую следующие действия:
3.2.1. Для i от 1 до 3 повторять:
3.2.2.1. Используя системные вызовы CreateProcess, создать два процесса Sort с классами приоритетов, в соответствии с вариантом задания. Необходимо, чтобы каждый процесс имел собственную консоль и окно консоли имело заголовок: "Process: NP; Prioritet: PP", где NP – номер процесса (1 или 2), а PP – приоритет соответствующего процесса. (Для изменения свойств окна консоли использовать структуру STARTUPINFO).
3.2.2.2. Ожидать окончания процессов, созданных в п. 3.2.2.1 (использовать функцию WaitForSingleObject).
Зафиксировать для отчета значения времени, получаемые при выполнении процессов в п 3.2.1.
Написать программу Threads, содержащую процедуру сортировки массива (разработанную при выполнении пункта 3.1), содержащего N/50 элементов и процедуру вывода массива на экран – mass_print. Программа должна выполнять следующие действия:
Генерировать случайный массив, содержащий N/50 элементов.
Используя системные вызовы CreateThread, создать программные потоки sort и mass_print в приостановленном состоянии.
Установить приоритеты потоков в THREAD_PRIORITY_NORMAL, используя системный вызов SetThreadPriority.
Активизировать потоки, используя системные вызовы ResumeThread;
3. Тексты программ
Программа Sort:
//---------------------------------------------------------------------------
#include <vcl.h>
#pragma hdrstop
#include <iostream>
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#include <math.h>
typedef int T; /* type of item to be sorted */
typedef int tblIndex; /* type of subscript */
#define compGT(a,b) (a > b)
using namespace std;
const int ITER = 1000; //количество итераций
const int ARRAY_SIZE = 3400; //размер массива по варианту
//---------------------------------------------------------------------------
void puzSort(T *a) {
tblIndex n, i, j;
T t;
for(j=ARRAY_SIZE-1;j>=0;j--)
for(i=0;i<=j-1;i++)
if(a[i]<a[i+1]){
n=a[i];
a[i]=a[i+1];
a[i+1]=n;}
}
//вывод времени
void timePrint(double time, const char * typeTime)
{
time = (double)time / CLOCKS_PER_SEC;
double miliSec, sec, min = 0;
miliSec = modf (time , &sec);
modf(miliSec * 1000, &miliSec);
min = sec / 60;
sec = int(sec) % 60;
double buf = miliSec;
int nums = 0;
while( buf >= 1 )
{
nums++;
buf /= 10;
}
char * nulls ="";
switch( nums )
{
case 0:
nulls = "000";
break;
case 1:
nulls = "00";
break;
case 2:
nulls = "0";
break;
}
printf("%s time - %.0f:%0.f:%s%0.f\n", typeTime, min, sec, nulls, miliSec);
}
#pragma argsused
int main(int argc, char* argv[])
{
if (argc!=2) {
cerr<<"Sort: Run MASTER.EXE first\n";
cin.get();
exit(1);
}
double duration, sortTime;
clock_t start, finish;
start = clock();
timePrint( start, "Start" );
start = clock();
int a[ARRAY_SIZE];
srand ( time(NULL) );
for(int i = 0; i < ITER; i++)
{
for(int j = 0; j < ARRAY_SIZE; j++)
a[j] = rand() % 10000 + 1;
puzSort(a);
}
finish = clock();
duration = finish - start;
timePrint(duration, "Duration");
sortTime = (finish - start) / ITER;
timePrint(sortTime, "Sorting");
int pid=atoi(argv[1]);
HANDLE process=OpenProcess(PROCESS_QUERY_INFORMATION | SYNCHRONIZE, FALSE, pid);
if (!process) cout<<"Sort: Process opening error\n";
cout<<"Sort: Waiting Master's finish\n";
cout.flush();
if (WaitForSingleObject(process,INFINITE)==STATUS_WAIT_0)
cout<<"Sort: Master finished\n";
else
cout<<"Sort: Unknown error\n";
cin.get();
return 0;
}
//---------------------------------------------------------------------------
Программа Master:
//---------------------------------------------------------------------------
#include <vcl.h>
#pragma hdrstop
#include <stdio.h>
#include <windows.h>
#include <iostream.h>
#include <string.h>
using namespace std;
//---------------------------------------------------------------------------
#pragma argsused
int main(int argc, char* argv[])
{
char cmd[128];
if (argc!=1)
strcpy(cmd,argv[1]);
else
strcpy(cmd,"Sort.exe");
/*
int pid=GetCurrentProcessId();
sprintf(cmd+strlen(cmd)," %d",pid);
*/
for(int i = 0; i < 3; i++)
{
cout<<"Iteration " << i+1 << "; Process 1" << "\n";
cout.flush();
STARTUPINFO info;
memset(&info,0,sizeof(info));
PROCESS_INFORMATION firstProcessInfo;
PROCESS_INFORMATION secondProcessInfo;
DWORD dwCreationFlags;
dwCreationFlags = CREATE_NEW_CONSOLE;
switch( i )
{
case 0:
dwCreationFlags |= IDLE_PRIORITY_CLASS;
info.lpTitle = "Process: 1; Prioritet: IDLE_PRIORITY_CLASS";
break;
case 1:
dwCreationFlags |= IDLE_PRIORITY_CLASS;
info.lpTitle = "Process: 1; Prioritet: IDLE_PRIORITY_CLASS";
break;
case 2:
dwCreationFlags |= NORMAL_PRIORITY_CLASS;
info.lpTitle = "Process: 1; Prioritet: NORMAL_PRIORITY_CLASS";
break;
}
info.cb=sizeof(info);
if (! CreateProcess(NULL,cmd,NULL,NULL,FALSE,dwCreationFlags,
NULL,NULL,&info,&firstProcessInfo))
{
cout<<"Master: can't run Sort\n";
cout<<"Master: check entered process name";
return -1;
}
cout<<"Iteration " << i+1 << "; Process 2" << "\n";
cout.flush();
dwCreationFlags = CREATE_NEW_CONSOLE;
memset(&info,0,sizeof(info));
switch( i )
{
case 0:
dwCreationFlags |= NORMAL_PRIORITY_CLASS;
info.lpTitle = "Process: 2; Prioritet: NORMAL_PRIORITY_CLASS";
break;
case 1:
dwCreationFlags |= HIGH_PRIORITY_CLASS;
info.lpTitle = "Process: 2; Prioritet: HIGH_PRIORITY_CLASS";
break;
case 2:
dwCreationFlags |= NORMAL_PRIORITY_CLASS;
info.lpTitle = "Process: 2; Prioritet: NORMAL_PRIORITY_CLASS";
break;
}
info.cb=sizeof(info);
if (! CreateProcess(NULL,cmd,NULL,NULL,FALSE,dwCreationFlags,
NULL,NULL,&info,&secondProcessInfo))
{
cout<<"Master: can't run Sort\n";
cout<<"Master: check entered process name";
return -1;
}
if(i < 2)
cout << "Going to the next iteration..." << "\n";
WaitForSingleObject( firstProcessInfo.hProcess, INFINITE );
WaitForSingleObject( secondProcessInfo.hProcess, INFINITE );
}
}
//---------------------------------------------------------------------------
Программа Threads.cpp:
//---------------------------------------------------------------------------
#include <vcl.h>
#pragma hdrstop
#include <iostream>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <time.h>
#include <math.h>
typedef int T; /* type of item to be sorted */
typedef int tblIndex; /* type of subscript */
#define compGT(a,b) (a > b)
using namespace std;
const int ARRAY_SIZE = 68; //(размер массива)/50
int a[ARRAY_SIZE];
//---------------------------------------------------------------------------
void puzSort(T *a) {
tblIndex n, i, j;
T t;
for(j=ARRAY_SIZE-1;j>=0;j--)
for(i=0;i<=j-1;i++)
if(a[i]<a[i+1]){
n=a[i];
a[i]=a[i+1];
a[i+1]=n;}
}
DWORD WINAPI mass_print(LPVOID Sender)
{
for(int i = 0; i < ARRAY_SIZE; i++)
printf("%d ", a[i]);
printf("\n");
return 0;
}
DWORD WINAPI sort(LPVOID Sender)
{
puzSort(a);
return 0;
}
#pragma argsused
int main(int argc, char* argv[])
{
for(int j = 0; j < ARRAY_SIZE; j++)
a[j] = rand() % 10000 + 1;
DWORD sortThreadId; // Id потока сортировки
DWORD massPrintThreadId; // Id потока вывода
DWORD sortdwCreationFlag; // параметр создания потока сортировки
DWORD massPrintdwCreationFlag; // параметр создания потока вывода
HANDLE sortHandle; // Дескриптор потока сортировки
HANDLE massPrintHandle; // Дескриптор потока вывода
sortdwCreationFlag = CREATE_SUSPENDED;
massPrintdwCreationFlag = CREATE_SUSPENDED;
sortHandle = CreateThread( NULL, 0, sort, 0, sortdwCreationFlag, &sortThreadId );
massPrintHandle = CreateThread( NULL, 0, mass_print, 0, massPrintdwCreationFlag, &massPrintThreadId );
SetThreadPriority( sortHandle, THREAD_PRIORITY_HIGHEST );
SetThreadPriority( massPrintHandle, THREAD_PRIORITY_IDLE );
ResumeThread( sortHandle );
ResumeThread( massPrintHandle );
// Wait until all threads have terminated.
WaitForSingleObject(sortHandle, INFINITE);
WaitForSingleObject(massPrintHandle, INFINITE);
// Close all thread handles and free memory allocations.
CloseHandle(sortHandle);
CloseHandle(massPrintHandle);
cin.get();
return 0;
}
//---------------------------------------------------------------------------