|
22.04.2012, 18:36
|
#1
|
|
|
|
Разведчик
|
Регистрация: 17.01.2012
Сообщений: 19
Популярность: 126
Сказал(а) спасибо: 8
Поблагодарили 30 раз(а) в 11 сообщениях
|
Реализация многопоточности
Реализация многопоточности в delphi. Вижу множество вопросов на разных форумах по программированию которые относятся к многопоточности. В этой статье я бы хотел не только объяснить как реализовать это в delphi, но и предоставить готовый шаблон многопоточного приложения который вы бы могли использовать в дальнейшем в своих программах.
Для начала немного теории. Одной из важнейших вещей в многопоточном приложении является синхронизация потоков. Если не учесть, синхронизацию потоков, то это, может привести к плачевным последствиям. Давайте рассмотрим такой пример, после чего у вас в голове всё встанет на свои места.
У нас в программе имеется переменная, назовём её - "int" - типа integer. Если мы будем присваивать ей значение из основного потока, то всё будет хорошо, и проблем не возникнет. Мало того, если даже мы присвоим ей значение из дополнительного потока который мы создали, то всё будет хорошо. Но так как зачастую у многопоточного приложения более одного дополнительного потока, то зададимся вопросом- "А, что будет если мы попытаемся присвоить переменной значение из двух потоков одновременно?". Вот тут, и произойдёт то таинственное события при котором переменной присвоится значение которое скорее всего не будет равно ни одному из значений которых вы планировали ей присвоить. Тогда и вступает в игру метод синхронизации synchronize. С помощь данного нам разработчиками delphi метода, вы можете обеспечить безопасное обращение нескольких потоков к одной переменной. Данный метод обеспечивает следующие: при вызове процедуры с помощью synchronize она начинает выполнятся, а все остальные процедуры вызванные с помощью этого метода встают в очередь и ждут выполнения текущей процедуры. Всё вышеописанное относится только к записи переменных, а читать можно одновременно из нескольких потоков и ничего плохого не произойдёт. Ну а теперь перейдём к практике.
И так создадим новый проект. И начнём писать поток. После вот этих строк:
Код:
private
{ Private declarations }
public
{ Public declarations }
end;
Добавим свои:
Код:
potok = class(TThread) //Этой строкой мы унаследовали класс потока
private
str: string;//в разделе private описываются переменные с помощью которых мы
nomer : Integer;//будем передавать значения между процедурами внутри потока
protected
procedure Execute; override;//это главная процедура потока, она начинает свою работу
//после того как мы создали поток
public
procedure synchro;//в разделе public вы можете объявить процедуры какие только душе
//угодно
constructor Create(CreateSuspended: Boolean);//эта строка говорит о том, что мы в
//implementation опишем конструкцию
//потока
end;
Ну здесь вроде бы всё понятно, вы можете добавлять сколько угодно переменных и процедур для удобства работы.
Под implementation нам надо описать конструкцию потока, в данном примере это не обязательно, но, что бы вы знали на будущие мы всё равно это сделаем.
Код:
constructor potok.Create(CreateSuspended: Boolean);
begin
inherited Create(CreateSuspended);//Эта строка говорит о том, что поток после создания
//будет приостановлен если ему передать значение true при создание, если false, то сразу
//начнёт работу.
end;
Добавим в глобальные переменные переменную - "nom" - типа integer, а так же массив наших потоков.
Код:
var
Form1: TForm1;
nom:integer;
a: array [1..10] of potok;//массив для хранения наших потоков
Теперь нужно описать процедуры потока, под implementation добавляем следующие:
Код:
procedure potok.Execute;//начинаем описывать главную процедуру потока
var
i:integer;
begin
for i:=0 to 100 do
begin
sleep(1000);
synchronize(synchro);//этой строкой мы вызываем процедуру synchro в единичном экземпляре
end;
end;
procedure potok.synchro; //описываем ещё одну процедуру потока, которая будет менять
//загаловок form1
begin
inc(nom);
form1.Caption:='Поток делает своё дело - '+inttostr(nom);
end;
Собственно всё готово, остаются только запустить потоки. Кидаем кнопку на форму, "кастуем на неё даблклик" и пишем:
Код:
procedure TForm1.Button1Click(Sender: TObject);
var
pot:integer;
begin
for pot:=1 to 10 do //цикл запускает 10 потоков, которые будут изменять заголовок
a[pot]:=potok.Create(false); //формы, так же идёт
//добавление в массив, что бы потом вы могли уничтожить
//один поток.
end;
Вот так выглядит программа в итоге:
Код:
unit Unit1;
interface
uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, StdCtrls;
type
TForm1 = class(TForm)
Button1: TButton;
procedure Button1Click(Sender: TObject);
private
{ Private declarations }
public
{ Public declarations }
end;
potok = class(TThread) //Этой строкой мы унаследовали класс потока
private
str: string;//в разделе private описываются переменные с помощью которых мы
nomer : Integer;//будем передавать значения между процедурами внутри потока
protected
procedure Execute; override;//это главная процедура потока, она начинает свою работу
//после того как мы создали поток
public
procedure synchro;//в разделе public вы можете объявить процедуры какие только душе
//угодно
constructor Create(CreateSuspended: Boolean);//эта строка говорит о том, что мы в
//implementation опишем конструкцию
//потока
end;
var
a: array [1..10] of potok;
Form1: TForm1;
nom:integer;
implementation
constructor potok.Create(CreateSuspended: Boolean);
begin
inherited Create(CreateSuspended);//Эта строка говорит о том, что поток после создания
//будет приостановлен если ему передать значение true при создание, если false, то сразу
//начнёт работу.
end;
{$R *.dfm}
procedure TForm1.Button1Click(Sender: TObject);
var
pot:integer;
begin
for pot:=1 to 10 do //цикл запускает 10 потоков, которые будут изменять заголовок
a[pot]:=potok.Create(false); //формы, так же идёт добавление в массив, что бы потом вы могли их уничтожить по одному.
end;
procedure potok.Execute;//начинаем описывать главную процедуру потока
var
I:integer;
begin
for i:=0 to 100 do
begin
sleep(1000);
synchronize(synchro);//этой строкой мы вызываем процедуру synchro в единичном экземпляре
end;
end;
procedure potok.synchro; //описываем ещё одну процедуру потока, которая будет менять
//загаловок form1
begin
inc(nom);
form1.Caption:='Поток делает своё дело - '+inttostr(nom);
end;
end.
Запускаем программу, и нажимаем на кнопку. И видим как в заголовке формы по очереди увеличивается число. ЧТД как говорится. Удачи в создание приложений.
С уважением Tip.the.besT.
Автор: Tip.the.besT
|
|
|
2 пользователя(ей) сказали cпасибо:
|
|
22.04.2012, 22:39
|
#2
|
|
|
|
Лейтенант-командор
|
Регистрация: 12.08.2010
Сообщений: 727
Популярность: 30569
Золото Zhyk.Ru: 1
Сказал(а) спасибо: 57
Поблагодарили 645 раз(а) в 386 сообщениях
|
Re: Реализация многопоточности
А где про всеми любимые критические секции?
________________
Принимаются пожертвования любых размеров в фонд поддержки начинающих программистов
Кошельки: WMZ - Z276844220882; WMR - R231028582939; WMU - U394136909210; ЯД - 410011494605270.
Perfect World: PWDatabaseScanner, Client, PWNickRenamer, PWClientRenamer, База логинов PW, Гайд по варУ, Зарабатываем репутацию.
Delphi: Авторизация на сайте с помощью Indy, Загрузка изображений с интернета в TImage с помощью Indy, Автоматическая смена стандартной версии Indy в Delphi на Indy 10.0.76 / 10.1.5, Основы парсинга с помощью Indy, Делаем Updater до программы с помощью Indy.
Other: ShowIP, FFUUU смайлы в QIP, Как играть в Minecraft (видеокурс), Как мы захватили человечество :D, Энергия в Лицемер/TopFace, PasGen.
|
|
|
23.04.2012, 01:38
|
#3
|
|
|
|
Разведчик
|
Регистрация: 17.01.2012
Сообщений: 19
Популярность: 126
Сказал(а) спасибо: 8
Поблагодарили 30 раз(а) в 11 сообщениях
|
Re: Реализация многопоточности
|
|
|
17.05.2012, 07:12
|
#4
|
|
|
|
Разведчик
|
Регистрация: 17.05.2012
Сообщений: 18
Популярность: 66
Сказал(а) спасибо: 20
Поблагодарили 20 раз(а) в 11 сообщениях
|
Re: Реализация многопоточности
Спасибо огромное только что дописал брут
Брутит на много быстрее жаль спасибо не могу дать
А как сделать что бы пользователь сам выберал сколько потоков?
|
|
|
20.05.2012, 12:46
|
#5
|
|
|
|
Разведчик
|
Регистрация: 30.09.2010
Сообщений: 4
Популярность: 10
Сказал(а) спасибо: 0
Поблагодарили 0 раз(а) в 0 сообщениях
|
Re: Реализация многопоточности
хмм... без крит. секций странно (:
сделал, НО пропускает валидные аккаунты T_T
при чем чем больше потоков, тем больше пропускает...
уже около месеца воюю с потоками и так и не чего не навоивал (:
|
|
|
20.05.2012, 13:31
|
#6
|
|
|
|
Разведчик
|
Регистрация: 17.01.2012
Сообщений: 19
Популярность: 126
Сказал(а) спасибо: 8
Поблагодарили 30 раз(а) в 11 сообщениях
|
Re: Реализация многопоточности
|
Цитата: |
|
|
|
|
|
|
|
|
|
хмм... без крит. секций странно (:
сделал, НО пропускает валидные аккаунты T_T
при чем чем больше потоков, тем больше пропускает...
уже около месеца воюю с потоками и так и не чего не навоивал (:
|
|
|
|
|
|
КС не юзаю, только метод синхронайз.
Дело наверно не в потоках. Ты смотрел в снифере, тебе хост отвечает на твой запрос?
Нужно ставить проверку, ответил ли хост или нет. Если не ответил, то ещё раз посылаем. Вот так будет робить. Для лёгкого алгоритма советую, генерировать лист - логин;пасс, а не брать из по отдельности. Тогда будет возможность удалять строку пока её обрабатывает поток и добавлять в конец списка если не удалось отправить запрос.
Так что, повоюй ещё с моими советами и думаю всё получится
|
Цитата: |
|
|
|
|
|
|
|
|
|
Спасибо огромное только что дописал брут
Брутит на много быстрее жаль спасибо не могу дать
А как сделать что бы пользователь сам выберал сколько потоков?
|
|
|
|
|
|
Теперь можешь)
Юзаем edit и всё. Где кол-во потоков вставляем:
Код:
strtoint(edit1.text)
Последний раз редактировалось Tip.the.besT; 20.05.2012 в 13:37.
|
|
|
Пользователь сказал cпасибо:
|
|
20.05.2012, 15:02
|
#7
|
|
|
|
Лейтенант-командор
|
Регистрация: 12.08.2010
Сообщений: 727
Популярность: 30569
Золото Zhyk.Ru: 1
Сказал(а) спасибо: 57
Поблагодарили 645 раз(а) в 386 сообщениях
|
Re: Реализация многопоточности
________________
Принимаются пожертвования любых размеров в фонд поддержки начинающих программистов
Кошельки: WMZ - Z276844220882; WMR - R231028582939; WMU - U394136909210; ЯД - 410011494605270.
Perfect World: PWDatabaseScanner, Client, PWNickRenamer, PWClientRenamer, База логинов PW, Гайд по варУ, Зарабатываем репутацию.
Delphi: Авторизация на сайте с помощью Indy, Загрузка изображений с интернета в TImage с помощью Indy, Автоматическая смена стандартной версии Indy в Delphi на Indy 10.0.76 / 10.1.5, Основы парсинга с помощью Indy, Делаем Updater до программы с помощью Indy.
Other: ShowIP, FFUUU смайлы в QIP, Как играть в Minecraft (видеокурс), Как мы захватили человечество :D, Энергия в Лицемер/TopFace, PasGen.
|
|
|
Пользователь сказал cпасибо:
|
|
21.05.2012, 16:01
|
#8
|
|
|
|
Разведчик
|
Регистрация: 07.12.2011
Сообщений: 8
Популярность: 364
Сказал(а) спасибо: 11
Поблагодарили 87 раз(а) в 36 сообщениях
|
Re: Реализация многопоточности
полезная информация!)
Можно ли как-то предотвратить пропускание..?
|
|
|
2 пользователя(ей) сказали cпасибо:
|
|
21.05.2012, 17:56
|
#9
|
|
|
|
Разведчик
|
Регистрация: 17.01.2012
Сообщений: 19
Популярность: 126
Сказал(а) спасибо: 8
Поблагодарили 30 раз(а) в 11 сообщениях
|
Re: Реализация многопоточности
|
|
|
2 пользователя(ей) сказали cпасибо:
|
|
21.05.2012, 18:22
|
#10
|
|
|
|
Разведчик
|
Регистрация: 30.09.2010
Сообщений: 4
Популярность: 10
Сказал(а) спасибо: 0
Поблагодарили 0 раз(а) в 0 сообщениях
|
Re: Реализация многопоточности
|
|
|
15.06.2012, 06:14
|
#11
|
|
|
|
Разведчик
|
Регистрация: 17.01.2012
Сообщений: 19
Популярность: 126
Сказал(а) спасибо: 8
Поблагодарили 30 раз(а) в 11 сообщениях
|
Re: Реализация многопоточности
|
|
|
20.06.2012, 04:49
|
#12
|
|
|
|
Сержант
|
Регистрация: 06.06.2012
Сообщений: 131
Популярность: 102
Сказал(а) спасибо: 141
Поблагодарили 131 раз(а) в 78 сообщениях
|
Re: Реализация многопоточности
как потоки на паузу поставить ? возможно ли такое ?
и если отправляем пост запрос ну например авторизацию на сайте почему потоки не будут работать без TRY EXCEPT ?
|
|
|
20.06.2012, 05:39
|
#13
|
|
|
|
Разведчик
|
Регистрация: 17.01.2012
Сообщений: 19
Популярность: 126
Сказал(а) спасибо: 8
Поблагодарили 30 раз(а) в 11 сообщениях
|
Re: Реализация многопоточности
|
|
|
Пользователь сказал cпасибо:
|
|
20.06.2012, 09:48
|
#14
|
|
|
|
Сержант
|
Регистрация: 06.06.2012
Сообщений: 131
Популярность: 102
Сказал(а) спасибо: 141
Поблагодарили 131 раз(а) в 78 сообщениях
|
Re: Реализация многопоточности
|
|
|
20.06.2012, 20:43
|
#15
|
|
|
|
Пехотинец
|
Регистрация: 23.03.2012
Сообщений: 83
Популярность: 908
Сказал(а) спасибо: 102
Поблагодарили 144 раз(а) в 61 сообщениях
|
Re: Реализация многопоточности
|
|
|
Ваши права в разделе
|
Вы не можете создавать новые темы
Вы не можете отвечать в темах
Вы не можете прикреплять вложения
Вы не можете редактировать свои сообщения
HTML код Выкл.
|
|
|
Заявление об ответственности / Список мошенников
Часовой пояс GMT +4, время: 15:23.
|
|