Форум программистов, компьютерный форум, киберфорум
Наши страницы
Delphi для начинающих
Войти
Регистрация
Восстановить пароль
 
 
Рейтинг 4.65/37: Рейтинг темы: голосов - 37, средняя оценка - 4.65
Melko
4 / 4 / 0
Регистрация: 07.01.2012
Сообщений: 243
#1

Дополнительный поток: как реализовать

05.04.2012, 19:17. Просмотров 6612. Ответов 131
Метки нет (Все метки)

Добрый день! Помогите пожалуйста добавить поток в программу, просто не могу сам разобраться в потоках.
И ещё не большая просьба - дайте какой ни будь очень простой пример потоков. Вся литература, посвящённая этой теме, уж больно не понятная
Заранее спасибо!
Delphi
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
unit deleter;
 
interface
 
uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs, StdCtrls, Menus;
 
type
  TForm1 = class(TForm)
    Memo1: TMemo;
    Memo2: TMemo;
    Button1: TButton;
    MainMenu1: TMainMenu;
    N1: TMenuItem;
    N2: TMenuItem;
    N3: TMenuItem;
    N4: TMenuItem;
    OpenDialog1: TOpenDialog;
    SaveDialog1: TSaveDialog;
    Button2: TButton;
    N5: TMenuItem;
    N6: TMenuItem;
    Button3: TButton;
    CheckBox1: TCheckBox;
    Button4: TButton;
    procedure Button1Click(Sender: TObject);
    procedure N6Click(Sender: TObject);
    procedure N2Click(Sender: TObject);
    procedure Button3Click(Sender: TObject);
    procedure Button2Click(Sender: TObject);
    procedure N5Click(Sender: TObject);
    procedure FormCreate(Sender: TObject);
    procedure Button4Click(Sender: TObject);
    procedure N3Click(Sender: TObject);
    procedure N4Click(Sender: TObject);
  private
    { Private declarations }
  public
    { Public declarations }
  end;
 
var
  Form1: TForm1;
 
implementation
 
{$R *.dfm}
 
procedure TForm1.Button1Click(Sender: TObject);
var
i:integer;
f, j:integer;
begin
for i:=0 to memo1.Lines.Count -1 do
begin
repeat
if ansipos(memo2.Text,memo1.Lines[i])<>0 then
memo1.Lines.Delete(i);
until
ansipos(memo2.Text,memo1.Lines[i])=0;
if checkbox1.Checked then
begin
For f:=Memo1.Lines.Count-1 downto 0 do
For j:=f-1 downto 0 do
If Memo1.Lines[f]=Memo1.Lines[j] then
Memo1.Lines.Delete(f);
end;
end;
end;
 
procedure TForm1.N6Click(Sender: TObject);
var
i:integer;
begin
for i:=0 to memo1.Lines.Count -1 do
begin
repeat
if ansipos(memo2.Text,memo1.Lines[i])<>0 then
memo1.Lines.Delete(i);
until
ansipos(memo2.Text,memo1.Lines[i])=0;
if ansipos(memo2.Text,memo1.Lines[i])=0 then
showmessage('Готово!');
end;
end;
 
procedure TForm1.N2Click(Sender: TObject);
begin
if opendialog1.execute=true then
memo1.Lines.LoadFromFile(opendialog1.FileName);
end;
 
procedure TForm1.Button3Click(Sender: TObject);
var
i, j:integer;
begin
For i:=Memo1.Lines.Count-1 downto 0 do
For j:=i-1 downto 0 do
If Memo1.Lines[i]=Memo1.Lines[j] then
Memo1.Lines.Delete(i);
 
end;
 
procedure TForm1.Button2Click(Sender: TObject);
begin
if savedialog1.execute=true then
memo1.Lines.SaveToFile(savedialog1.Filename);
end;
 
procedure TForm1.N5Click(Sender: TObject);
begin
if savedialog1.execute=true then
memo1.Lines.SaveToFile(savedialog1.Filename);
 
end;
 
procedure TForm1.FormCreate(Sender: TObject);
begin
memo1.Clear;
memo2.Clear;
end;
 
procedure TForm1.Button4Click(Sender: TObject);
begin
if opendialog1.execute=true then
memo1.Lines.LoadFromFile(opendialog1.FileName);
end;
 
procedure TForm1.N3Click(Sender: TObject);
begin
form1.Close;
end;
 
procedure TForm1.N4Click(Sender: TObject);
begin
MessageDlg('Прогу заебенил Kloud :D', mtinformation, [mbOk], 0);
 
end;
 
end.
Добавлено через 1 час 39 минут
Помогите кто нибудь
Уж очень хочется с потоками разобраться
0
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
Similar
Эксперт
41792 / 34177 / 6122
Регистрация: 12.04.2006
Сообщений: 57,940
05.04.2012, 19:17
Ответы с готовыми решениями:

Дополнительный поток и внешние функции\процедуры
Приветствую Вас, победители восставших компиляторов. Возник небольшой вопрос,...

Поток освобождается, но переменная, которой был присвоен этот поток, не очищается
Мне интересно, вот поток отработал, стоит FreeOnTerminate:=True; Поток...

Как приостановить поток?
var I: Integer; begin Thread := sSpinEdit2.Value; for I := 0 to...

Как уничтожить поток?
procedure TForm1.FormClose(Sender: TObject; var Action: TCloseAction); begin...

Как остановить поток
Здравствуйте, у меня в потоке выполняется код, а именно запрос idhttp1.get...

131
Melko
4 / 4 / 0
Регистрация: 07.01.2012
Сообщений: 243
11.04.2012, 19:09  [ТС] #41
Цитата Сообщение от Одиночка Посмотреть сообщение
Psilon: Ну написал человек наоборот, я не стал менять, чтобы не запутывать его ещё больше.

Это так должен быть написан Unit1:
Delphi
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
unit Unit1;
 
interface
 
uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs, StdCtrls, unit2;
 
type
  TForm1 = class(TForm)
    Memo1: TMemo;
    Button1: TButton;
    procedure Button1Click(Sender: TObject);
  private
    { Private declarations }
  public
    { Public declarations }
  end;
 
var
  Form1: TForm1;
 
implementation
 
{$R *.dfm}
 
procedure TForm1.Button1Click(Sender: TObject);
begin                  //было пробущено начало блока
   tpotok:=potok.Create(TRUE); //Создаём переменную tpotok типа potok
   tpotok.Priority:=TpLowest;    //Устанавливаем приоритет потока
   tpotok.resume;                   //Запускаем поток
//  potok.create(true); //Это неправильно
//  potok.resume;
end;
 
end.
А так должен быть написан Unit2:

Delphi
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
unit Unit2;
 
interface
 
uses
  Classes, SysUtils;
 
type
  potok = class(TThread)
  private
    { Private declarations }
  protected
    procedure Execute; override;
    procedure loading;
  end;
 
  Tpotok:potok;
 
implementation
uses Unit1;
 
{ potok }
 
//Ошибка ................................
//Процедуры Loading и Execute - это два разных метода потока. Зачем ты их запихнул в Loading?
procedure potok.loading;
var
  i, j:integer;
begin
  For i:=Memo1.Lines.Count-1 downto 0 do
  For j:=i-1 downto 0 do
  If Memo1.Lines[i]=Memo1.Lines[j] then
  Memo1.Lines.Delete(i);
end;
 
procedure potok.Execute;
begin
  synchronize(loading);
end;
 
end.
Я, просто, что бы не переписывать код вручную, его скопировал, по этому и пропустил begin
А вот на счёт "зачем всё в один запихнул?" я не очень понял. Я делал по принципу execute - синхронизация, а loading - код

Добавлено через 3 минуты
Цитата Сообщение от Psilon Посмотреть сообщение
Melko, это объявление типа, а не объявление переменной. Для типов работают только присваивания, тип не может принадлежать к какому-то типу, он может в себя включать стандартные (или один стандартный). К тому же почитайте, что вам компилятор пишет и какие значки рисует.
Я знаю, что он написал что то вроди "стоит ";" а ожидалось ":"", только вот когда менял - ни к чему хорошему это не привело

Добавлено через 3 минуты
Всё! Я понял из-за чего сыр бор
у меня после "implementation" не написан "var"
Ещё раз прошу прощения, просто делал наспех, а после правки забыл вставить немного исправленный код
0
Одиночка
3933 / 1858 / 337
Регистрация: 16.03.2012
Сообщений: 3,869
11.04.2012, 19:11 #42
Ну end, которое у меня стоит 34-й строкой, у тебя стояло после того, который у меня 39-й.

Да, а var я и не заметил.

Psilon: Насчёт того, что компилятор ругается на resume. Думаю в более продвинутых Дельфях компилятор уже видит, что поток сразу запускается после создания и считает, что это некорректный код. Хотя кто его знает.
0
Melko
4 / 4 / 0
Регистрация: 07.01.2012
Сообщений: 243
11.04.2012, 19:16  [ТС] #43
Теперь возникают другие ошибки
unit1
Delphi
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
unit Unit1;
 
interface
 
uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs, StdCtrls, unit2;
 
type
  TForm1 = class(TForm)
    Memo1: TMemo;
    Button1: TButton;
    procedure Button1Click(Sender: TObject);
  private
    { Private declarations }
  public
    { Public declarations }
  end;
 
var
  Form1: TForm1;
 
implementation
 
{$R *.dfm}
 
procedure TForm1.Button1Click(Sender: TObject);
begin
tpotok:=potok.Create(TRUE); //ÑîçäГ*ВёГ¬ ïåðåìåГ*Г*ГіГѕ tpotok ГІГЁГЇГ* potok
tpotok.Priority:=TpLowest;    //ÓñòГ*Г*Г*âëèâГ*ГҐГ¬ ïðèîðèòåò ïîòîêГ*
tpotok.resume;
end;
 
end.

unit2
Delphi
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
unit Unit2;
 
interface
 
uses
  Classes, SysUtils;
 
type
  potok = class(TThread)
  private
    { Private declarations }
  protected
    procedure Execute; override;
    procedure loading;
  end;
   var
  Tpotok:potok;
 
implementation
uses Unit1;
{ Important: Methods and properties of objects in visual components can only be
  used in a method called using Synchronize, for example,
 
      Synchronize(UpdateCaption);
 
  and UpdateCaption could look like,
 
    procedure potok.UpdateCaption;
    begin
      Form1.Caption := 'Updated in a thread';
    end; }
 
{ potok }
 
procedure potok.loading;
var
i, j:integer;
begin
For i:=Memo1.Lines.Count-1 downto 0 do
For j:=i-1 downto 0 do
If Memo1.Lines[i]=Memo1.Lines[j] then
Memo1.Lines.Delete(i);
end;
procedure potok.Execute;
begin
  synchronize(loading);
end;
 
end.
0
Миниатюры
Дополнительный поток: как реализовать  
Одиночка
3933 / 1858 / 337
Регистрация: 16.03.2012
Сообщений: 3,869
11.04.2012, 19:20 #44
В Unit2 везде вместо Memo1 нужно писать: Form1.Memo1.
1
Psilon
Master of Orion
Эксперт .NET
5993 / 4846 / 901
Регистрация: 10.07.2011
Сообщений: 14,459
Записей в блоге: 5
Завершенные тесты: 4
11.04.2012, 19:23 #45
Одиночка,
Цитата Сообщение от Rad Studio Delphi XE2
[DCC Warning] MergeSortUnit.pas(287): W1000 Symbol 'Resume' is deprecated
Try to avoid using Suspend and Resume in most circumstances. Suspending and resuming a thread using these two functions can result in undefined behavior and in deadlock situations that are hard to debug and fix later on. Proper thread synchronization techniques should be based on TEvent, TMutex, and critical sections.
1
Melko
4 / 4 / 0
Регистрация: 07.01.2012
Сообщений: 243
11.04.2012, 19:27  [ТС] #46
Всем спасибо, только я не получил ожидаемого результата - я по прежнему не могу передвигать программу, но при её повторном выделении, она не зависает(это уже плюс ). Что посоветуете?
0
Psilon
Master of Orion
Эксперт .NET
5993 / 4846 / 901
Регистрация: 10.07.2011
Сообщений: 14,459
Записей в блоге: 5
Завершенные тесты: 4
11.04.2012, 19:30 #47
Melko, добавьте в поток фразу
Delphi
1
Application.ProcessMessages
Т.е.
Delphi
1
2
3
4
5
6
7
8
9
10
11
procedure potok.loading;
var
  i, j:integer;
begin
For i:=Memo1.Lines.Count-1 downto 0 do
  For j:=i-1 downto 0 do begin
    Application.ProcessMessages
    If Memo1.Lines[i]=Memo1.Lines[j] then
       Memo1.Lines.Delete(i);
  end;
end;
0
Одиночка
3933 / 1858 / 337
Регистрация: 16.03.2012
Сообщений: 3,869
11.04.2012, 19:31 #48
Psilon: И это наверное правильно. Но в данном случае это просто тупость компилятора.
А вообще я в таком режиме не работал, поэтому и не задумывался, что приостанов может произойти в критической секции.

Не по теме:

Кстати. Сдал свою программу?



Не по теме:

Блин, получается целая отладка через интернет. Проще,конечно, самому написать весь код, отладить и потом отдавать.

0
Melko
4 / 4 / 0
Регистрация: 07.01.2012
Сообщений: 243
11.04.2012, 19:35  [ТС] #49
[Error] Unit2.pas(41): Missing operator or semicolon
[Error] Unit2.pas(41): Undeclared identifier: 'Application'
з.ы: 41-ой строчкой стоит Application.ProcessMessages;
0
Одиночка
3933 / 1858 / 337
Регистрация: 16.03.2012
Сообщений: 3,869
11.04.2012, 19:39 #50
В uses unit2 вставь ещё ссылку на модуль Forms.
1
Psilon
Master of Orion
Эксперт .NET
5993 / 4846 / 901
Регистрация: 10.07.2011
Сообщений: 14,459
Записей в блоге: 5
Завершенные тесты: 4
11.04.2012, 19:40 #51

Не по теме:

Кстати. Сдал свою программу?
Во-первых препод не пришел, перенесли на потом.
Во-вторых я делал это уже сверх задания, мне достаточно было, чтобы программа работала (вплоть до примитивного консольного приложения). А распараллеливание и пр - это уже моё пожелание по углублению знаний дельфей. :)
А за помощь кстати спасибо.


Melko,
Я бы на вашем месте не парился с многопоточностью а все запилил в один первый модуль:
Delphi
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
unit Unit1;
 
interface
 
uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs, StdCtrls, unit2;
 
type
  TForm1 = class(TForm)
    Memo1: TMemo;
    Button1: TButton;
    procedure Button1Click(Sender: TObject);
  private
    { Private declarations }
  public
    { Public declarations }
  end;
 
var
  Form1: TForm1;
 
implementation
 
{$R *.dfm}
 
procedure TForm1.Button1Click(Sender: TObject);
var
  i, j:integer;
begin
For i:=Memo1.Lines.Count-1 downto 0 do
  For j:=i-1 downto 0 do begin
    Application.ProcessMessages
    If Memo1.Lines[i]=Memo1.Lines[j] then
       Memo1.Lines.Delete(i);
  end;
end;
 
end.
0
Melko
4 / 4 / 0
Регистрация: 07.01.2012
Сообщений: 243
11.04.2012, 19:44  [ТС] #52
Цитата Сообщение от Одиночка Посмотреть сообщение
В uses unit2 вставь ещё ссылку на модуль Forms.
Да, теперь всё в порядке, спасибо

Добавлено через 58 секунд
А нельзя как нибудь побольше скорость выполнения сделать? А то 20000 строк уже минуту обрабатывает
0
Одиночка
3933 / 1858 / 337
Регистрация: 16.03.2012
Сообщений: 3,869
11.04.2012, 19:45 #53
Psilon:
Я бы на вашем месте не парился с многопоточностью а все запилил в один первый модуль
Я уже об этом говорил. Но человек хотел разобраться с потоками на простом примере.
1
Melko
4 / 4 / 0
Регистрация: 07.01.2012
Сообщений: 243
11.04.2012, 19:46  [ТС] #54
Цитата Сообщение от Psilon Посмотреть сообщение

Не по теме:


Во-первых препод не пришел, перенесли на потом.
Во-вторых я делал это уже сверх задания, мне достаточно было, чтобы программа работала (вплоть до примитивного консольного приложения). А распараллеливание и пр - это уже моё пожелание по углублению знаний дельфей. :)
А за помощь кстати спасибо.


Melko,
Я бы на вашем месте не парился с многопоточностью а все запилил в один первый модуль:
Delphi
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
unit Unit1;
 
interface
 
uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs, StdCtrls, unit2;
 
type
  TForm1 = class(TForm)
    Memo1: TMemo;
    Button1: TButton;
    procedure Button1Click(Sender: TObject);
  private
    { Private declarations }
  public
    { Public declarations }
  end;
 
var
  Form1: TForm1;
 
implementation
 
{$R *.dfm}
 
procedure TForm1.Button1Click(Sender: TObject);
var
  i, j:integer;
begin
For i:=Memo1.Lines.Count-1 downto 0 do
  For j:=i-1 downto 0 do begin
    Application.ProcessMessages
    If Memo1.Lines[i]=Memo1.Lines[j] then
       Memo1.Lines.Delete(i);
  end;
end;
 
end.
Мне многопоточность нужна для другой программы, а эта - чисто изучение и проверка на работоспособность потока
0
Одиночка
3933 / 1858 / 337
Регистрация: 16.03.2012
Сообщений: 3,869
11.04.2012, 19:48 #55
Melko: А чего за задача то?

Psilon: За ту помощь ты меня уже благодарил. Я просто вспомнил, как бы мы же уже знакомые, а не просто так.
0
Psilon
Master of Orion
Эксперт .NET
5993 / 4846 / 901
Регистрация: 10.07.2011
Сообщений: 14,459
Записей в блоге: 5
Завершенные тесты: 4
11.04.2012, 19:50 #56
А нельзя как нибудь побольше скорость выполнения сделать? А то 20000 строк уже минуту обрабатывает
Конечно. Просто надо грузить в массив строк, а не в стринггрид. Как у моего знакомого, который делал программу парсинга математических операций, анализ длился 3мс, в treeview загружалось 50 секунд.

Многопоточность нужна либо для ОЧЕНЬ длительных операций (Если учесть, какие сейчас числодробилки а-ля 2500K), либо для того, чтобы отрубить процесс (например, как в моем случае работа кнопки "отмена"). В остальных случаях параллельные потоки особо не нужны имхо.
0
Одиночка
3933 / 1858 / 337
Регистрация: 16.03.2012
Сообщений: 3,869
11.04.2012, 19:56 #57
Psilon: Кстати. В твоём случае, для того, чтобы рубить выполнение, не было необходимости делать дополнительный поток.
Я практическим путём выяснил, что даже если идёт длительная обработка в основном потоке, то события кнопок всё равно отрабатываются и управление возвращается в то место, где было прервано. Я использовал это, чтобы прервать динамику отображения спирографа.
0
Melko
4 / 4 / 0
Регистрация: 07.01.2012
Сообщений: 243
11.04.2012, 20:06  [ТС] #58
Цитата Сообщение от Psilon Посмотреть сообщение
Конечно. Просто надо грузить в массив строк, а не в стринггрид. Как у моего знакомого, который делал программу парсинга математических операций, анализ длился 3мс, в treeview загружалось 50 секунд.

Многопоточность нужна либо для ОЧЕНЬ длительных операций (Если учесть, какие сейчас числодробилки а-ля 2500K), либо для того, чтобы отрубить процесс (например, как в моем случае работа кнопки "отмена"). В остальных случаях параллельные потоки особо не нужны имхо.
Так мне, получается, нужно не в мемо, а в тривью загружать текст, для увеличения скорости, или как?
У меня изучение дельфи на начальном уровне стоит, то есть я основы знаю, но книжек не читал, по этому иногда переспрашиваю

Добавлено через 2 минуты
Вот ещё вопрос, он не обязательный, а просто хотелось бы узнать
Часто в программах, которые с текстовиками работают, возникает ошибка "out of memory" - её можно как то избежать, т.е. загружать файлы очень большого размера?
0
Одиночка
3933 / 1858 / 337
Регистрация: 16.03.2012
Сообщений: 3,869
11.04.2012, 20:09 #59
Melko: Напиши, какая задача. В зависимости от задачи можно выбрать метод решения. А Psilon имел ввиду либо создавать Array[..] of string, либо в StrinList.
1
Psilon
Master of Orion
Эксперт .NET
5993 / 4846 / 901
Регистрация: 10.07.2011
Сообщений: 14,459
Записей в блоге: 5
Завершенные тесты: 4
11.04.2012, 20:09 #60
Так мне, получается, нужно не в мемо, а в тривью загружать текст, для увеличения скорости, или как?
У меня изучение дельфи на начальном уровне стоит, то есть я основы знаю, но книжек не читал, по этому иногда переспрашиваю
Я говорю про то, что если проанализировать объект, лежащий в памяти - дело займет несколько микросекунд, если делать то же самое с визуальным компонентом - время пойдет на минуты
Часто в программах, которые с текстовиками работают, возникает ошибка "out of memory" - её можно как то избежать, т.е. загружать файлы очень большого размера?
Вообще-то выгружать файлы целиком в оперативку это ОЧЕНЬ плохой тон. Если бы те люди, которые занимались внешней сортировкой (вы же слышали про 640КБ для всех? ) узнали бы, что так будут делать, они бы застрелились, инфа 100%


Одиночка, а поподробнее? В моем случае программа просто висла, а потом эксплорер её целиком обрубал.
1
11.04.2012, 20:09
MoreAnswers
Эксперт
37091 / 29110 / 5898
Регистрация: 17.06.2006
Сообщений: 43,301
11.04.2012, 20:09

Как запустить поток из таймера?
не получается запустить потоки из таймера, при создании потока из кнопки все...

Как определить закончил ли работу поток?
Здравствуйте, как определить закончил ли работу поток? begin Potok1 :=...

Как лучше добавить процедуру в поток?
Есть процедура, которая воспроизводит файл. В зависимости от checkbox'a на...


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
60
Ответ Создать тему
Опции темы

КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin® Version 3.8.9
Copyright ©2000 - 2018, vBulletin Solutions, Inc.
Рейтинг@Mail.ru