mirror of
https://github.com/loginov-dmitry/multithread.git
synced 2024-11-28 09:33:03 +02:00
Исправлен раздел "Коротко о приоритетах Windows"
This commit is contained in:
parent
a82e6738f1
commit
21ebfbad66
@ -5,7 +5,7 @@ object Form1: TForm1
|
||||
#1055#1088#1086#1075#1088#1072#1084#1084#1072' '#1076#1083#1103' '#1086#1087#1088#1077#1076#1077#1083#1077#1085#1080#1103' '#1076#1083#1080#1090#1077#1083#1100#1085#1086#1089#1090#1080' '#1074#1099#1076#1077#1083#1103#1077#1084#1099#1093' '#1082#1074#1072#1085#1090#1086#1074' '#1074#1088#1077#1084#1077#1085 +
|
||||
#1080
|
||||
ClientHeight = 434
|
||||
ClientWidth = 646
|
||||
ClientWidth = 730
|
||||
Color = clBtnFace
|
||||
Font.Charset = DEFAULT_CHARSET
|
||||
Font.Color = clWindowText
|
||||
@ -16,7 +16,7 @@ object Form1: TForm1
|
||||
OnCreate = FormCreate
|
||||
OnDestroy = FormDestroy
|
||||
DesignSize = (
|
||||
646
|
||||
730
|
||||
434)
|
||||
PixelsPerInch = 96
|
||||
TextHeight = 19
|
||||
@ -58,6 +58,13 @@ object Form1: TForm1
|
||||
Height = 19
|
||||
Caption = #1055#1088#1080#1074#1103#1079#1072#1090#1100' '#1082' '#1103#1076#1088#1091' CPU:'
|
||||
end
|
||||
object Label5: TLabel
|
||||
Left = 296
|
||||
Top = 83
|
||||
Width = 206
|
||||
Height = 19
|
||||
Caption = #1055#1088#1080#1086#1088#1080#1090#1077#1090' '#1087#1077#1088#1074#1086#1075#1086' '#1087#1086#1090#1086#1082#1072':'
|
||||
end
|
||||
object edThreadCount: TEdit
|
||||
Left = 192
|
||||
Top = 52
|
||||
@ -68,7 +75,7 @@ object Form1: TForm1
|
||||
end
|
||||
object btnStartThreads: TButton
|
||||
Left = 304
|
||||
Top = 103
|
||||
Top = 110
|
||||
Width = 297
|
||||
Height = 41
|
||||
Caption = #1047#1072#1087#1091#1089#1090#1080#1090#1100' '#1087#1086#1090#1086#1082#1080' '#1085#1072' 10 '#1089#1077#1082#1091#1085#1076
|
||||
@ -78,11 +85,12 @@ object Form1: TForm1
|
||||
object Memo1: TMemo
|
||||
Left = 8
|
||||
Top = 167
|
||||
Width = 630
|
||||
Width = 714
|
||||
Height = 259
|
||||
Anchors = [akLeft, akTop, akRight, akBottom]
|
||||
ScrollBars = ssVertical
|
||||
TabOrder = 2
|
||||
ExplicitWidth = 630
|
||||
end
|
||||
object clbCPUList: TCheckListBox
|
||||
Left = 192
|
||||
@ -100,6 +108,25 @@ object Form1: TForm1
|
||||
Caption = #1048#1089#1087#1086#1083#1100#1079#1086#1074#1072#1090#1100' '#1088#1072#1079#1085#1099#1077' '#1087#1088#1080#1086#1088#1080#1090#1077#1090#1099
|
||||
TabOrder = 4
|
||||
end
|
||||
object cbPriority: TComboBox
|
||||
Left = 506
|
||||
Top = 80
|
||||
Width = 216
|
||||
Height = 27
|
||||
Style = csDropDownList
|
||||
ItemHeight = 19
|
||||
ItemIndex = 3
|
||||
TabOrder = 5
|
||||
Text = 'tpNormal '
|
||||
Items.Strings = (
|
||||
'tpIdle '
|
||||
'tpLowest '
|
||||
'tpLower '
|
||||
'tpNormal '
|
||||
'tpHigher '
|
||||
'tpHighest'
|
||||
'tpTimeCritical')
|
||||
end
|
||||
object Timer1: TTimer
|
||||
Interval = 500
|
||||
OnTimer = Timer1Timer
|
||||
|
@ -38,6 +38,8 @@ type
|
||||
Label4: TLabel;
|
||||
clbCPUList: TCheckListBox;
|
||||
cbUseDiffPriority: TCheckBox;
|
||||
Label5: TLabel;
|
||||
cbPriority: TComboBox;
|
||||
procedure btnStartThreadsClick(Sender: TObject);
|
||||
procedure FormCreate(Sender: TObject);
|
||||
procedure FormDestroy(Sender: TObject);
|
||||
@ -63,8 +65,8 @@ var
|
||||
APriority: TThreadPriority;
|
||||
begin
|
||||
Memo1.Clear;
|
||||
//APriority := tpNormal;
|
||||
APriority := tpHigher;
|
||||
|
||||
APriority := TThreadPriority(cbPriority.ItemIndex);
|
||||
for I := 1 to StrToInt(edThreadCount.Text) do
|
||||
begin
|
||||
if cbUseDiffPriority.Checked and (I > 1) then
|
||||
|
@ -128,13 +128,13 @@ Delphi – это прежде всего инструмент для разра
|
||||
|
||||
# 2. Базовый класс многопоточности - TThread <a name="class_tthread"></a>
|
||||
|
||||
TThread – это базовый класс, инкапсулирующий функционал для обеспечения работы параллельного потока. Если мы хотим реализовать код, который должен выполняться в отдельном потоке, то нам необходимо реализовать наследника от класса TThread и, как минимум, реализовать override-метод Execute. Код, находящийся внутри метода Execute будет исполняться в отдельном потоке.
|
||||
`TThread` – это базовый класс, инкапсулирующий функционал для обеспечения работы параллельного потока. Если мы хотим реализовать код, который должен выполняться в отдельном потоке, то нам необходимо реализовать наследника от класса `TThread` и, как минимум, реализовать override-метод Execute, который перекроет виртуальный абстрактный метод `Execute`, объявленный в родительском классе `TThread`. Код, находящийся внутри метода `Execute` будет исполняться в отдельном потоке.
|
||||
|
||||
При создании класса-наследника от TThread мы можем реализовать конструктор, деструктор, объявить собственные поля, методы, свойства и т.д., в зависимости от поставленной перед нами задачи.
|
||||
При создании класса-наследника от `TThread` мы можем реализовать конструктор, деструктор, объявить собственные поля, методы, свойства и т.д., в зависимости от поставленной перед нами задачи.
|
||||
|
||||
В данном разделе я не буду подробно останавливаться на описании возможностей класса TThread. Читайте внимательно следующие разделы, надеюсь, в них Вы найдёте необходимую для Вас информацию.
|
||||
|
||||
:information_source: **Информация!** *Дополнительные потоки создаются с помощью вызова соответствующей функции операционной системы, например CreateThread в ОС Windows. Класс TThread является обёрткой, которая добавляет к системному дополнительному потоку объектно-ориентированное измерение, т.е. позволяет создать объект, который привязывается к системному дополнительному потоку.*
|
||||
:information_source: **Информация!** *Дополнительные потоки создаются с помощью вызова соответствующей функции операционной системы, например `CreateThread` в ОС Windows. Класс `TThread` является обёрткой, которая добавляет к системному дополнительному потоку объектно-ориентированное измерение, т.е. позволяет создать объект, который привязывается к системному дополнительному потоку.*
|
||||
|
||||
:information_source: **Информация!** Существуют и другие популярные средства для многопоточного программирования в Delphi. К ним стоит отнести:
|
||||
\- **Parallel programming library** - стандартная библиотека для параллельного программирования в современных версиях Delphi.
|
||||
@ -972,6 +972,8 @@ end.
|
||||
|
||||
8) Кнопка `btnRunInParallelThread` может быть нажата произвольное количество раз.
|
||||
|
||||
:warning: **Внимание!** *Функции `InterlockedIncrement` и `InterlockedDecrement` являются частью Windows API. В современных версиях Delphi Вы можете использовать их кроссплатформенные аналоги: `AtomicIncrement` и `AtomicDecrement`*.
|
||||
|
||||
# 5. Передача информации из дополнительного потока в основной <a name="send_info_to_main_thread"></a>
|
||||
|
||||
При разработке многопоточных приложений в Delphi очень актуальной является задача передачи информации, подготовленной в дополнительном потоке, в главный поток. Это весьма сложная тема, требующая от Delphi-программиста повышенного внимания, т.к. при недостаточных знаниях у программиста есть очень высокий шанс сделать программу глюченной и нестабильной.
|
||||
@ -1972,14 +1974,17 @@ end;
|
||||
tpTimeCritical) platform;
|
||||
{$ENDIF MSWINDOWS}
|
||||
```
|
||||
Обычно программисту нет смысла изменять приоритеты потоков. Приоритет потока никак не влияет на скорость исполнения программного кода. Приоритет потока никак не влияет на размер кванта времени. Относительный приоритет потока работает только в рамках процесса и никак не влияет на выделение квантов времени потокам, которые работают в других процессах.
|
||||
Обычно программисту нет смысла изменять приоритеты потоков. Приоритет потока никак не влияет на скорость исполнения программного кода. Приоритет потока никак не влияет на размер кванта времени (однако размер кванта времени зависит от того, является ли приложение активным или нет, т.е. у неактивного приложения квант времени примерно в 3 раза меньше, чем у активного).
|
||||
|
||||
Изменять приоритет потока не имеет никакого смысла, если выполняется задача, в которой основное время уходит на ожидание какого-либо события.
|
||||
Относительный приоритет потока влияет на выделение процессорного времени как между потоками в рамках одного процесса, так и между потоками различных процессов.
|
||||
|
||||
Изменять приоритет потока не имеет смысла, если выполняется задача, в которой основное время уходит на ожидание какого-либо события.
|
||||
|
||||
Если в Вашей программе работают 2 потока, у одного приоритет `tpNormal`, а у второго `tpLower` и оба потока привязаны к одному и тому же ядру процессора, то первому потоку гораздо чаще будет предоставляться процессорное время (например, 98%). С другой стороны, если у этих же потоков не будет привязки к одному и тому же ядру, то они получат одинаковое процессорное время. Скорее всего, оба варианта – это не то, чего Вы хотите добиться при изменении относительного приоритета потока.
|
||||
|
||||
Существует 2 крайних уровня приоритетов: `tpIdle` и `tpTimeCritical`. Поток с приоритетом `tpIdle` получит процессорное время только в том случае, если нет других активных потоков с более высоким приоритетом. Поток с приоритетом `tpTimeCritical` будет забирать себе всё процессорное время, т.е. потоки с более низким приоритетом не получат квант времени, если выполняется поток с приоритетом `tpTimeCritical`. Это верно для одноядерного процессора. Если процессор многоядерный (сейчас это обычная ситуация), то, скорее всего, будут выполняться одновременно и поток с приоритетом `tpIdle` и поток с приоритетом `tpTimeCritical`.
|
||||
|
||||
:information_source: **Внимание!** *В каталоге CalcTimeQuant находится программа, позволяющая производить эксперименты с приоритетами и замеры длительности квантов времени.*
|
||||
|
||||
<!--
|
||||
:warning: **Внимание!**
|
||||
|
Loading…
Reference in New Issue
Block a user