параллельная обработка запросов

  • Автор темы -
  • Дата начала

Гость
#1
и еще задам такой вопрос.
Кто нибудь занимался разработкой приложения для параллельной обработки запросов?
пробовала через CheckBox, но, если честно, результатов пока никаких..
подскажите пожалуйста как вообще начать? я в полном ступоре
 

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

Гость
#3
sax_ol, поделитесь, пожалуйста, если знаете где взять.
 

Гость
#4
сделала так, но кнопка стоп и параллельность хромают на все что можно, точнее даже не работают. предлагают сделать через фазы блокировки, но так и не нашка как это сделать.
прошу помочь



Код:
unit Unit8;

interface

uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, DBCtrls, StdCtrls, ExtCtrls, Grids, DBGrids ,ShellApi, dblookup,
CheckLst;

type
TMyThread1 = class(TThread)
private
{ Private declarations }
protected
procedure DoWork;
procedure Execute; override;
end;

TMyThread2 = class(TThread)
private
{ Private declarations }
protected
procedure DoWork;
procedure Execute; override;
end;

TForm8 = class(TForm)
DBGrid1: TDBGrid;
Button1: TButton;
Button2: TButton;
Label1: TLabel;
Label2: TLabel;
Label3: TLabel;
Label4: TLabel;
DBLookupComboBox1: TDBLookupComboBox;
DBLookupComboBox2: TDBLookupComboBox;
DBLookupComboBox3: TDBLookupComboBox;
DBLookupComboBox4: TDBLookupComboBox;
DBLookupComboBox5: TDBLookupComboBox;
CheckListBox1: TCheckListBox;
Button3: TButton;
procedure Button1Click(Sender: TObject);
procedure Button2Click(Sender: TObject);
procedure Button3Click(Sender: TObject);
procedure FormShow(Sender: TObject);






private
{ Private declarations }
public
{ Public declarations }
end;

var
Form8: TForm8;
a: string;
T1  : TMyThread1;
T2  : TMyThread2;
implementation

uses Unit2;

{$R *.dfm}
procedure TMyThread1.Execute;
begin
{Пока процесс не прервали, выполняем DoWork}
while not Terminated do
Synchronize(DoWork);
end;

procedure TMyThread2.Execute;
begin
{Пока процесс не прервали, выполняем DoWork}
while not Terminated do
Synchronize(DoWork);
end;

procedure TMyThread1.DoWork;
begin
{Пытаемся победить второй процесс :-)}
Form8.CheckListBox1.Checked[1]:= True;
end;

procedure TMyThread2.DoWork;
begin
{Пытаемся победить первый процесс :-)}
Form8.CheckListBox1.Checked[0]:= False;
end;

procedure TForm8.Button3Click(Sender: TObject);
begin
if Button3.Caption = 'Stop' then begin
// Прерываем оба процесса
T1.Terminate;
T2.Terminate;
// Изменяем название кнопки
Button3.Caption := 'Start';
// Выходим из процедуры
Exit;
end;
//Создаем и сразу запускаем два процесса
T1 := TMyThread1.Create(False);
T2 := TMyThread2.Create(False);
// Переименовываем кнопку
Button3.Caption := 'Stop';
end;

procedure TForm8.Button1Click(Sender: TObject);
begin
with DataModule2.ADOQuery1 do
begin close;
SQL.Clear;
datamodule2.adoquery1.Active:=false;
if CheckListBox1.Checked[0]=true then begin
datamodule2.ADOquery1.Close;
datamodule2.ADOquery1.SQl.Clear;
datamodule2.ADOquery1.sql.add('SELECT s.Familia as [Фамилия] ,s.Imya as [Имя] , s.Otchestvo as [Отчество] , s.Telefon as [Телефон], g.fakultet as [Факультет], g.Kafedra as [Кафедра] ');
datamodule2.ADOquery1.sql.add('FROM Gruppi as g, Studenti as s');
datamodule2.ADOquery1.sql.add('WHERE g.fakultet = :myparam');
datamodule2.ADOquery1.Parameters.ParamByName('myparam').Value := dblookupcombobox4.text;
datamodule2.ADOquery1.Open;
end;

if CheckListBox1.Checked[1]=true then begin
datamodule2.ADOquery1.Close;
datamodule2.ADOquery1.SQl.Clear;
datamodule2.ADOquery1.sql.add('select d.specializaciya as [Специализация],d.familia as [Фамилия], d.imya as [Имя], d.otchestvo as [Отчество], d.telefon as [Телефон]');
datamodule2.ADOquery1.sql.add('from Prepod as d');
datamodule2.ADOquery1.sql.add('where d.specializaciya = :myparam');
datamodule2.ADOquery1.Parameters.ParamByName('myparam').Value := dblookupcombobox5.text;
datamodule2.ADOquery1.Open;
end;

if CheckListBox1.Checked[2]=true then begin
datamodule2.ADOquery1.Close;
datamodule2.ADOquery1.SQl.Clear;
datamodule2.ADOquery1.sql.add( 'select g.kurator as [Куратор], g.Kafedra as [Кафедра],g.fakultet as[Факультет],g.№_gruppi as [№группы]');
datamodule2.ADOquery1.sql.add('from Gruppi as g');
datamodule2.ADOquery1.sql.add('where g.№_gruppi = :myparam');
datamodule2.ADOquery1.Parameters.ParamByName('myparam').Value := dblookupcombobox1.text;
datamodule2.ADOquery1.Open;
end;

if CheckListBox1.Checked[3]=true then begin
datamodule2.ADOquery1.Close;
datamodule2.ADOquery1.SQl.Clear;
datamodule2.ADOquery1.sql.add( 'select p.nazvanie as [Название], p.Tip as [Тип предмета], p.obem as [Количество часов] ');
datamodule2.ADOquery1.sql.add('from Predmeti as p');
datamodule2.ADOquery1.sql.add('where p.Tip = :myparam');
datamodule2.ADOquery1.Parameters.ParamByName('myparam').Value := dblookupcombobox2.text;
datamodule2.ADOquery1.Open;

end;

if CheckListBox1.Checked[4]=true then begin
datamodule2.ADOquery1.Close;
datamodule2.ADOquery1.SQl.Clear;
datamodule2.ADOquery1.sql.add('select p.Prepod as [N], d.familia as [Фамилия], p.nazvanie as [Предмет], p.obem as [Кол-во часов], p.Semestri as [Семестры], p.obem/p.Semestri as [Нагрузка] ');
datamodule2.ADOquery1.sql.add('from Prepod d inner join Predmeti p on p.Prepod=d.kod_prepod ');
datamodule2.ADOquery1.sql.Add('where d.kod_prepod = :myparam');
datamodule2.ADOquery1.Parameters.ParamByName('myparam').Value := dblookupcombobox3.KeyValue;
datamodule2.ADOquery1.Open;
end;
end;
end;

procedure TForm8.Button2Click(Sender: TObject);

// тут html отчет, нафиг никому не нужный
end;







procedure TForm8.FormShow(Sender: TObject);
begin
DataModule2.ADOTable3.Active := true;
end;


end.
 

sinkopa

Well-Known Member
17.06.2009
344
9
#5
сделала так, но кнопка стоп и параллельность хромают на все что можно, точнее даже не работают. предлагают сделать через фазы блокировки, но так и не нашка как это сделать.
прошу помочь
...
А можно узнать (в двух трех словах)... а какое поведение программы ожидалось?
Честно скажу... почитал Ваш код, не понял нихрена... :please:
Пока я вижу следующее:
1. Есть основная нить (в процедуре procedure TForm8.Button1Click(Sender: TObject))
надо сказать сама по себе довольно противоречивая.
Ведь если правдиво больше одного условия... например
Код:
CheckListBox1.Checked[0]=true
и
Код:
CheckListBox1.Checked[1]=true
то результаты запроса в первом блоке тут же буквально будут потеряны...
ну да ладно... Тем не менее, в конце концов процедура отработает до конца и основная нить программы "выпадет" в петлю ожидания очередной команды пользователя...
с этим понятно (хотя общий смысл, повторяю, мне не ясен)...

2. Есть еще две "потусторонних" нити которые... (у меня другого определения нет) наперебой друг дружке пытаются загрузить процессор на 120% :(
Ну если бы внутри "DoWork" стоял какой нибудь "Sleep(100)" это хотя бы было похоже на генератор случайных кликов по чекбоксу...
Я уже не говорю о том, что TMyThread1.DoWork все время ВКЛЮЧАЕТ второй чекбокс а TMyThread2.DoWork все время ВЫКЛЮЧАЕТ первый... :blink:
безсмыслица?
Или Вы чтото от нас скрываете? признавайтесь? :rolleyes:

Расскажите пожалста, чего вы хотели добиться данным кодом... а то с телепанией у меня сегодня что то худо...
 

Гость
#6
все уже, я все решила))
sinkopa, а по поводу тредов я так сильно и не разобралась, так что пошла по пути наиеньшего сопротивленния ^^ сейчас понимаю сама, что этот код, особенно треды-хрень та еще, особенно в моем написании)
 
O

OasisInDesert

Гость
#7
подскажите пожалуйста как вообще начать? я в полном ступоре
Ого применили класс TThread, а говорите что в ступоре :)

В своих программках все запросы пускаю в отдельных потоках, что бы основное окно не "застывало".

Теперь о твоем коде
- Не понял цели создания потоков, ведь запросы к базе у тебя выполняются в основном потоке, видимо чисто для пробы.
- Мне не понравилось то что ты проверяешь состояние/статус основываясь на содержимом заголовка кнопки, заводи для этого отдельный флаг состояния, в данном указанном тобой случае можно просто повесить If assigned(Thread1) then ...
- Дальше интереснее, в условии ты просто терминируешь потоки, процедура terminate лишь выставляет флаг terminated в true, после чего потоки прекращают свое выполнение, однако! сами объекты классов TThread1 и TThread2 остаются в памяти!!! Для высвобождения памяти необходимо вручную уничтожать их вызовом метода Free или при создании указать чтобы при завершении потоки саморазрушались.
Код:
Thread1:=TThread1.Create(True); // Поток застыл
Thread1.FreeOnTerminate:=True; // Инициализируем поток
.....
Thread1.Resume; // Поток ожил

Будут вопросы задавай чем смогу помогу.