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;", то оба потока отрабатывают синхронно, но вся суть в том, чтобы они работали последовательно.


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

Твой пример только запутывает.


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

Медвежонок Пятачок, некоторые хранимки должны выполняться синхронно для сокращения общего времени процесса.

и чего?
создание потока в твоей программе увеличивает число ядер процессора sql сервера?


YURY   (2011-11-29 12:16:00) [43]

Медвежонок Пятачок, некоторые хранимки должны выполняться синхронно для сокращения общего времени процесса.


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

> YURY  (29.11.2011 12:08:07)  [7]

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


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

> Сергей М.  (29.11.2011 12:04:06)  [6]

Это потуму что они не умеют устранить зависание интерфейса другими методами.


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

Медвежонок Пятачок, ошибка эта возникает в боевой схеме

Про эту ошибку тебе уже несколько человек все рассказали.


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

В идеале должен быть поток-диспетчер, отвечающий за запуск доп.потоков (которые не должны знать ничегоо существовании друг друга) в нужной последовательности.

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


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

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


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

Пример реализован лишь для тестирования идеи.
поток должен выполнять свою хранимую процедуру
Цепочка последовательности выполнения процедур считывается из БД.

идея дебильная.
потоки не нужны.
так как последовательность выполнения детерминирована и лежит в бд, нужна одна хранимая процедура-диспетчер, которая выполнит все остальные хранимки.


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

Ну и при чем здесь тогда твой "Неверный дескриптор"?
если ты и так все знаешь и сам создал ошибку для простоты


YURY   (2011-11-29 12:08:00) [51]

Благодарю откликнувшихся, но видимо требуется уточнение. Пример реализован лишь для тестирования идеи. Идея в том, что все потоки должны быть одного класса. В зависимости от заданных параметров часть потоков должны стартовать синхронно, а определённые одни - строго поле определённых других других. VCL здесь не причём - сделал для простоты, тем более что и с VCL потоки синхронно работают, если убрать WaitFor. На деле же каждый поток должен выполнять свою хранимую процедуру, но определённые процедуры должны быть выполнены строго после окончания других. Цепочка последовательности выполнения процедур считывается из БД.


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


> Поток Б должен стартовать после завершения потока А


Теряется сам смысл использования двух потоков, тем более единого класса.


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

>   ptrEdit^.Text := IntToStr(i);// за это можно и на костер


Anatoly Podgoretsky   (2011-11-29 11:57:00) [54]

OnTerminate в первом или обеих потоках


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

> Поток Б должен стартовать после завершения потока А.
убивает всю идею с
> Требуется выполнить n потоков одного класса

достаточно 1 потока последовательно выполняющего n действий...

> Почему возникает ошибка и как её устранить?
а не обращайся к объектам VCL формы без синхронизации. или думаешь обманул систему своими указателями...?


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

Заодно сожги вот эту ересь.

ThreadArray[0].ptrEdit := @Edit1;
ptrEdit ^.Text := IntToStr(i);


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

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


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

Наверх

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