Процессы, потоки и нити в ОС Windows, страница 5

Листинг 7. Использование АРС

#define _WIN32_WINNT 0x0400

#include <windows.h>

#include <iostream.h>

volatile int waiting=0;

void CALLBACK apcfunc(DWORD)

{

waiting=1;

}

DWORD CALLBACK t1(LPVOID)

{

cout<<"Поток начал работу\n";

cout.flush();

Sleep(15000);

cout<<"Переходим в настороженное состояние\n";

cout.flush();

SleepEx(10000,TRUE);

MessageBox(NULL,"T1 завершил работу","Debug",MB_OK);

return 0;

}

void main()

{

HANDLE thread;

DWORD tid;

thread=CreateThread(NULL,0,t1,0,0,&tid);

Sleep(5000); // ждем, пока поток начнет работу

QueueUserAPC(apcfunc,(HANDLE)thread,0);

while (waiting==0);

MessageBox(NULL,"Поток выполнил функцию APC","Debug",MB_OK);

}

На рис. 5 представлен результат работы программы.

Рис. 5. Работа программы APC


Индивидуальное задание

Программа создает три потока и каждом запускает расчет разных сложных функций. После завершения потоков в главную программу возвращаются характеристики рабочего набора этих потоков и результаты выполнения расчетов. Вся информация выводится на экран.

Алгоритмработыпрограммы

С помощью функции GetCurrentThread() получим хендл главного процесса, затем с помощью функции _beginthread() , из библиотеки С++, создадим 3 потока, выполняющие расчёт разных сложных функций. Вывод результата осуществляется из функции main()

Текст программы

#include "stdafx.h"

#include <windows.h>

#include <process.h>  // необходимо для обращения к _beginthread

#include <stdio.h>

#include <time.h>

#include <iostream.h>

#include <math.h>

HANDLE mainthread,thread1,thread2,thread3;

int zn3, zn2,zn1;

/*DWORD*/ FILETIME td1,td2,td3,td4,td5,td6,td7,td8;

//char *thr_name []={"Первый","Второй","Третий"};//имена потоков

//int thread_on=1;

//далее идёт 3 потока для расчет разных сложных функций

/*unsigned long CALLBACK*/ void f1(void *)

{

thread1=GetCurrentThread();

zn1=1;

WaitForSingleObject(thread1,2000);

//GetProcessWorkingSetSize(thread1,&td1,&td2);           

//return(0);

}

/*unsigned long CALLBACK*/ void f2(void *)

{

thread2=GetCurrentThread();

zn2=2;

WaitForSingleObject(thread2,2000);

//GetProcessWorkingSetSize(thread2,&td3,&td4);           

//return(0);

}

/*unsigned long CALLBACK*/ void f3(void *)

{

thread3=GetCurrentThread();

zn3=3;

WaitForSingleObject(thread3,2000);

//GetProcessWorkingSetSize(thread3,&td5,&td6);

//return(0);

}

void main()

{

//DWORD tid1,tid2,tid3;

//void *p;

mainthread=GetCurrentThread();

_beginthread(f1,0,NULL);

_beginthread(f2,0,NULL);

_beginthread(f3,0,NULL);

/*           p=(void *)1;

CreateThread(NULL,0,f1,NULL,0,&tid1);

CreateThread(NULL,0,f2,NULL,0,&tid2);

CreateThread(NULL,0,f3,NULL,0,&tid3);*/

cout<<"\n"<<zn1<<"\n"<<zn2<<"\n"<<zn3<<"\n";

GetThreadTimes(thread1,&td1,&td2,&td3,&td4);

cout<<td1.dwLowDateTime<<"\n"<<td2.dwLowDateTime<<"\n"<<td3.dwLowDateTime<<"\n"<<td4.dwLowDateTime<<"\n";

GetThreadTimes(thread2,&td1,&td2,&td3,&td4);

cout<<td1.dwLowDateTime<<"\n"<<td2.dwLowDateTime<<"\n"<<td3.dwLowDateTime<<"\n"<<td4.dwLowDateTime<<"\n";

GetThreadTimes(thread2,&td1,&td2,&td3,&td4);

cout<<td1.dwLowDateTime<<"\n"<<td2.dwLowDateTime<<"\n"<<td3.dwLowDateTime<<"\n"<<td4.dwLowDateTime<<"\n";

}

Результат работы программы показан на рис. 6

Рис. 6. Результат работы программы
Cписок использованных источников

1. Р.САЙМОН, WINDOWS  2000 API ЭНЦИКЛОПЕДИЯ  ПРОГРАММИСТА, 2002

2. Тихомиров В.А. Маленькие Уроки большого API

3. Рихтер Д., Рихтер Д. Создание эффективных WIN32-приложений, 2001