Top.Mail.Ru
Мастера DELPHI, Delphi programming community Титульная страница Поиск, карта сайта Написать письмо 
| Новости | Поиск | FAQ | Статьи | Книги | Новости VCL |
| Форумы ЧАТ | Орешник | KOL и MCK |
Форумы -» Основная («Начинающим»)/ Базы / WinAPI / Компоненты / Сети / Media / Игры / Corba и COM / KOL / FreePascal / .Net / Прочее / RSDN.ORG

« предыдущая ветвь | форум | следующая ветвь »

Потоки [D7, WinXP]


Страницы:   1 2 3

YURY ©   (2011-11-29 11:42:00) 

Добрый день.
Требуется выполнить n потоков одного класса, каждый из которых будет выполнять свои действия в зависимости от заданных параметров. Поток Б должен стартовать после завершения потока А.
Реализую на простейшем примере из двух потоков (форма с двумя компонентами TEdit и кнопкой и модуль класса потока). При нажатии на кнопку первый поток должен выводить в первый TEdit значения от 0 до 20000, затем второй поток должен выводить во второй TEdit значения от 50000 до 70000. По факту же после завершения работы первого потока возникает ошибка "Thread error: Неверный дескриптор (6)" и второй поток не отрабатывает. Почему возникает ошибка и как её устранить?
Код для примера (форма и модуль):

unit Unit1;

interface

uses
 Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
 Dialogs, StdCtrls;

type
 TForm1 = class(TForm)
   Button1: TButton;
   Edit1: TEdit;
   Edit2: TEdit;
   procedure Button1Click(Sender: TObject);
 private
   { Private declarations }
 public
   { Public declarations }
 end;

var
 Form1: TForm1;

implementation

uses Unit2;

{$R *.dfm}

procedure TForm1.Button1Click(Sender: TObject);
var
 ThreadArray: Array of TMyThread;
begin
 SetLength(ThreadArray, 2);

 ThreadArray[0] := TMyThread.Create(True);
 ThreadArray[0].FreeOnTerminate := True;
 ThreadArray[0].Priority := tpNormal;
 ThreadArray[0].j := 0;
 ThreadArray[0].k := 20000;
 ThreadArray[0].ptrEdit := @Edit1;

 ThreadArray[1] := TMyThread.Create(True);
 ThreadArray[1].FreeOnTerminate := True;
 ThreadArray[1].Priority := tpNormal;
 ThreadArray[1].j := 50000;
 ThreadArray[1].k := 70000;
 ThreadArray[1].ptrEdit := @Edit2;
 ThreadArray[1].ptrThread := @ThreadArray[0];

 ThreadArray[0].Resume;
 ThreadArray[1].Resume;
end;

end.

unit Unit2;

interface

uses
 Classes, StdCtrls, SysUtils;

type
 TMyThread = class(TThread)
 public
   j, k: Integer;
   ptrEdit: ^TEdit;
   ptrThread: ^TMyThread;
 protected
   procedure Execute; override;
 end;

implementation

procedure TMyThread.Execute;
var
 i: Integer;
begin
 if Assigned(ptrThread) then ptrThread^.WaitFor;
 for i := j to k do
   ptrEdit^.Text := IntToStr(i);
end;

end.

P.S. Если в модуле потока убрать инструкцию "if Assigned(ptrThread) then ptrThread^.WaitFor;", то оба потока отрабатывают синхронно, но вся суть в том, чтобы они работали последовательно.


sniknik   (2011-11-29 12:55:00) [21]

> для сокращения общего времени процесса.
общее время процесса от добавления потоков всегда увеличивается...
http://russian.joelonsoftware.com/Articles/HumanTaskSwitchesConsider.html
параллельность нужна не для этого.


Медвежонок Пятачок   (2011-11-29 12:55:00) [22]

запускай на сервере.
нужна асинхронность - запускай через job'ы


YURY   (2011-11-29 12:53:00) [23]

Сергей М., Очерёдность у них определена во входных параметрах. Поэтому одни выполняются сразу, а иные попросту ждут завершения других. Никто ни за кем не шпионит. Так все же, как реализовать эту идею в одном классе? Если вернуться к примеру с VCL, то что не так и почему ошибка? Ведь второй поток таки ожидает завершения первого и только потом возникает исключение... Почему оно возникает и как его избежать?


Anatoly Podgoretsky   (2011-11-29 12:52:00) [24]

Зачем же врешь?

ThreadArray[0] := TMyThread.Create(True);

ThreadArray[1] := TMyThread.Create(True);


YURY   (2011-11-29 12:48:00) [25]

Я не упомянул, что сервер у нас оракловый и пользователей несколько сотен, так что в этом отношении всё нормально.


Сергей М.   (2011-11-29 12:47:00) [26]


> как с помощью этого одного класса реализовать возможность
> параллельного, а также последовательного запуска ХП, в зависимости
> от переданных параметров?


Да не должны вообще об этом заботиться потоки, исполняющие твои ХП !
Их дело - запускать на выполнение указанные им запросы.
А диспетчеризацией должен быть озабочен отдельныйпоток, если угодно -  доп.поток другогокласса или хоть тот же осн.поток.

А у тебя сейчас доп.потоки занимаются совсем несвойственной им работой - шпионят друг за другом в попытке определить свою очередность в этой каше)


YURY   (2011-11-29 12:46:00) [27]

Сергей М., может с точки зрения вашей теории это и глупости, но практика показывает значительное сокращение общего времени выполнения при параллельном запуске нескольких хранимых процедур. Реально:  Последовательное выполнение 12-ти боевых процедур занимает 4,5 часа. Их параллельное выполнение - чуть более полутора часов. Разница очевидна. Проверено многократно на различных наборах хранимок.


Anatoly Podgoretsky   (2011-11-29 12:43:00) [28]

> Сергей М.  (29.11.2011 12:35:25)  [25]

У меня 14 потоков забивают все ядра сервера по максимуму


Anatoly Podgoretsky   (2011-11-29 12:42:00) [29]

> Сергей М.  (29.11.2011 12:35:25)  [25]

И поставит сервер на колени


Медвежонок Пятачок   (2011-11-29 12:42:00) [30]

создать еще одну хранимую процедуру.
передавать в нее управляющую информацию что и в какой последовательности запускать.
выполнить ее.


Anatoly Podgoretsky   (2011-11-29 12:41:00) [31]

> YURY  (29.11.2011 12:26:23)  [23]

Ничего не значищие слова


YURY   (2011-11-29 12:40:00) [32]

Парни, попробую ещё раз, сжато.
Требуется выполнить набор хранимых процедур. Для ускорения общего времени выполнения какие-то из них нужно запускать одновременно, а какие-то - строго после окончания других (цепочка последовательности динамическая - по выбору пользователя - и находится в БД). Причём и набор хранимок также формируется пользователем динамически. Т.е. я не знаю заранее какие именно хранимки и в какой последовательности придётся выполнять. Это всё будет считано из БД в процессе выполнения. Потому и создан один класс потока, запускающего переданную ему в параметрах хранимую процедуру. Но вопрос остался - как с помощью этого одного класса реализовать возможность параллельного, а также последовательного запуска ХП, в зависимости от переданных параметров?


Сергей М.   (2011-11-29 12:35:00) [33]


> YURY   (29.11.11 12:28) [24]


> на практике параллельное выполнение различных хранимых процедур
> (каждую в своем потоке) значительно быстрее их последовательного
> выполнения. Проверено.
> <Цитата>


Глупости.
Даже если сервер умудрится идеально (что никогда не случится) распределить исполнение N твоих (и не только твоих - ты же не единственный клиент у сервера) параллельных запросов по своим N потокам, каждый из которых исполняется отдельным "свободным" ядром, то дальнейшее потенциальное увелечение N сведет всю "быстроту" на нет.


YURY   (2011-11-29 12:28:00) [34]

Сергей М., на практике параллельное выполнение различных хранимых процедур (каждую в своем потоке) значительно быстрее их последовательного выполнения. Проверено.


YURY   (2011-11-29 12:26:00) [35]

Anatoly Podgoretsky, для выполнения определённых действий в основном потоке (в боевой схеме).


Медвежонок Пятачок   (2011-11-29 12:25:00) [36]

А нашиша их параллельно-то на выполнение запускать ?

это потому что его очень умные потоки научены выполнять только одну хранимку.
запустить их несколько по списку - это задача на следующую пятилетку.


Сергей М.   (2011-11-29 12:23:00) [37]


> YURY   (29.11.11 12:19) [18]


Ну с последовательным синхронным выполнением ХП еще понятно.
А нашиша их параллельно-то на выполнение запускать ?
Серверу твои параллельно работающие потоки до лампочки - у него своя кухня из своих ядер, потоков и приоритетов.


Anatoly Podgoretsky   (2011-11-29 12:22:00) [38]

Создай два класса и запускай нужный. Не вижу нужды в одном


Anatoly Podgoretsky   (2011-11-29 12:21:00) [39]

И зачем ThreadArray?


YURY   (2011-11-29 12:19:00) [40]

Anatoly Podgoretsky, я не знаю заранее сколько хранимок и какие именно будут выполняться. Эта информация считывается из БД в процессе выполнения. Потому и реализован один класс потока, выполняющий задаваемую в параметрах хранимую процедуру.


Страницы:   1 2 3

Наверх

Титульная страница Поиск, карта сайта Написать письмо