Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
ответы.doc
Скачиваний:
1
Добавлен:
30.08.2019
Размер:
260.1 Кб
Скачать
  1. Создание потоков.

Каждый поток начинает выполнение с некоей входной функции. В первичном потоке таковой является main, wmain, WinMain или wWinMain. Если Вы хотите создать вторичный поток, в нем тоже должна быть входная функция, которая выглядит примерно так:

DWORD WINAPI ThreadFunc(PVOID pvParam)

{

DWORD dwResult = 0;

//...

return(dwResult);

}

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

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

Для создания дополнительных потоков, нужно вызвать из первичного потока функцию CreateThread:

HANDLE CreateThread (

1)PSECURITY_ATTRIBUTES psa;

2)DWORD cbStack;

3)PTHREAD_START_ROUTINE pfnStartAddr;

4)PVOID pvParam;

5)DWORD fdwCreate;

6)PDWORD pdwThreadID);

1) указатель на структуру SECURITY_ATTRIBUTES. Если Вы хотите, чтобы объекту ядра «поток» были присвоены атрибуты защиты по умолчанию – NULL. А чтобы дочерние процессы смогли наследовать описатель этого объекта – TRUE.

2) Этот параметр определяет, какую часть адресного пространства поток сможет использовать под свой стек.

3) адрес функции потока, с которой должен будет начать работу создаваемый поток

4) позволяет передавать функции потока какое-либо инициализирующее значение. Оно может быть или просто числовым значением, или указателем на структуру данных с дополнительной информацией.

5) дополнительные флаги, управляющие созданием потока. Он принимает одно из двух значений: 0 (исполнение потока начинается немедленно) или CREATE_SUSPENDED. В последнем случае система создает поток, инициализирует его и приостанавливает до последующих указаний. Флаг CREATE_SUSPENDED позволяет программе изменить какие-либо свойства потока перед тем, как он начнет выполнять код.

6) адрес переменной типа DWORD, в которой функция возвращает идентификатор, приписанный системой новому потоку.

  1. Динамический приоритет потока. Установка приоритета.

Каждому потоку присваивается уровень приоритета — от 0 (самый низкий) до 31 (самый высокий). Решая, какому потоку выделить процессорное время, система сначала рассматривает только потоки с приоритетом 31 и подключает их к процессору по принципу карусели. Если поток с приоритетом 31 не исключен из планирования, он немедленно получает квант времени, по истечении которого система проверяет, есть ли еще один такой поток. Если да, он тоже получает свой квант процессорного времени.

Пока в системе имеются планируемые потоки с приоритетом 31, ни один поток с более низким приоритетом процессорного времени не получает. Такая ситуация называется "голоданием* (starvation). Она наблюдается, когда потоки с более высоким приоритетом так интенсивно используют процессорное время, что остальные практически не работают.

При загрузке системы создается особый поток — поток обнуления страниц (zero page thread), которому присваивается нулевой уровень приоритета. Ни один поток, кроме этого, не может иметь нулевой уровень приоритета Он обнуляет свободные страницы в оперативной памяти при отсутствии других потоков, требующих внимания со стороны системы.

Windows поддерживает семь относительных приоритетов потоков

Относительный приоритет потока

Описание

Time-critical (критичный по времени)

Поток выполняется с приоритетом 31 в классе real-time и с приоритетом 15 в других классах

Highest (высший)

Поток выполняется с приоритетом на два уровня выше обычною для данного класса

Above normal (выше обычного)

Поток выполняется с приоритетом на один уровень выше обычного для данного класса

Normal (обычный)

Поток выполняется с обычным приоритетом процесса для данного класса

Below normal (ниже обычного)

Поток выполняется с приоритетом на один уровень ниже обычного для данного класса

Lowеst (низший)

Поток выполняется с приоритетом на два уровня ниже обычного для данного класса

Idle (простаивающий)

Поток выполняется с приоритетом 16 в классе real-time и с приоритетом 1 в других классах

Относительный приоритет потока

Idle

Класс приоритета процесса

Real-lime

Below normal

Normal

Above normal

Highest

Time-critical

15

15

15

15

15

31

Highest

6

8

10

12

15

26

Above normal

5

7

9

11

14

25

Normal

4

6

8

10

13

24

Below normal

3

5

7

9

12

23

Lowеst

2

4

6

8

11

22

Idle

1

1

1

1

1

16

Только что созданный поток получает относительный приоритет normal.

BOOL SetThreadPriority( HANDLE hThread, int nPriority);

Разумеется, параметр bThread указывает на поток, чей приоритет Вы хотите из менить, а через nPriority передается один из идентификаторов

Относительный приоритет потока

Идентификатор

Time-critical

THREAD_PRIORITY_TIME_CRITICAL

Highest

THREAD_PRIORITY_HIGHEST

Above normal

THREAD_PRIORITY_ABOVE_NORMAL

Normal

THREAD_PRIORITY_NORMAL

Below normal

THREAD_PRIORITY_BELOW_NORMAL

Lowest

THREAD_PRIORITY_LOWEST

Idle

THREAD_PRIORITY_IDLE

Функция GetThreadPnority, парная SetThreadPriority, позволяет узнать относительный приоритет потока.

int GetThreadPriority(HANDLE hThread);

Она возвращает один из идентификаторов, показанных в таблице выше.