Главная страница
Top.Mail.Ru    Яндекс.Метрика
Текущий архив: 2005.01.23;
Скачать: CL | DM;

Вниз

Остановка дочернего потока   Найти похожие ветки 

 
Priest   (2004-12-02 17:59) [0]

Что произойдёт, если дочерний поток остановить когда он выполняет метод, вызванный в Syncronize


 
Суслик ©   (2004-12-02 18:13) [1]

Как остановить?
Если suspend, то все повиснет на фиг.


 
jack128 ©   (2004-12-02 19:28) [2]

Суслик ©   (02.12.04 18:13) [1]
Если suspend, то все повиснет на фиг

это проверенный факт? На вскидку основной поток не должен остановиться..


 
Суслик ©   (2004-12-02 19:34) [3]


>  [2] jack128 ©   (02.12.04 19:28)

проверить надо, но думаю, что все повиснет

проверь - делов на 3 мин.


 
jack128 ©   (2004-12-02 21:57) [4]

ну так я хотел на халяву узнать.. А тут сиди проверяй.. :-) Нет, останавливается только тот поток, который Suspend"им. Основной работает нормально..

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

procedure TTest.Execute;
begin
 { Place thread code here }
 Self.Synchronize(Suspend);
end;

procedure TTest.SyncProc;
begin
 Suspend;
end;

procedure TForm1.Button1Click(Sender: TObject);
begin
 with TTest.Create(True) do
 begin
   FreeOnTerminate := True;
   Resume;
 end;
end;


 
Piter ©   (2004-12-02 22:14) [5]

Женька прав, Суслик не прав.

>SuspendThread(MainThreadID);

не останавливает главный поток, винда умная :)

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

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


 
Leonid Troyanovsky   (2004-12-02 22:27) [6]


> Piter ©   (02.12.04 22:14) [5]
> Женька прав, Суслик не прав.
>
> >SuspendThread(MainThreadID);
>
> не останавливает главный поток, винда умная :)


Т.е., у нее должно хватить ума сделать OpenThread?

--
С уважением, LVT.


 
Alexander Panov ©   (2004-12-02 22:31) [7]

Piter ©   (02.12.04 22:14) [5]
По идее, управление не вернется. Но так как главный поток остановить нельзя - то таким вопросом можно не озадачиваться...


А при чем тут управление?

>all

Synchronize выполняется в контексте основного потока, в это время дочерний поток находится в выполнении функции SendMessage. Если в этот момент остановить дочерний поток, то основной поток продолжит выполнение обработки сообщения, возвратит Msg.Result и спокойно будет продолжать работу дальше.

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

Так или нет?


 
Piter ©   (2004-12-02 23:13) [8]

Сорри, это я не так понял вопрос. Подумал, что останавливается главный поток, а там про дочерний...

А почему Суслик подумал, что встанет? Ведь Syncronize то выполняется в контексте основного потока, а останавливается дочерний. Почему это все встать должно?

jack128 ©   (02.12.04 21:57) [4]
procedure TTest.Execute;
begin
{ Place thread code here }
Self.Synchronize(Suspend);
end;


может

Self.Synchronize(SyncProc); ?


 
Piter ©   (2004-12-02 23:35) [9]

Leonid Troyanovsky   (02.12.04 22:27) [6]
Т.е., у нее должно хватить ума сделать OpenThread?


я тоже подумал, что MainThreadID - это ID потока, а нужен указатель на него. И тоже подумал про OpenThread. Но нигде (ни в справке, ни в файлах экспорта) не нашел описание такой функции. Только OpenThreadToken. Вот и подумал - может для потоков не так, как для процессов?
Или все таки есть функция OpenThread?

Alexander Panov ©   (02.12.04 22:31) [7]
Так или нет?


я думаю так. Только хочу заметить, что Syncronize через сообщения организован не во всех Дельфях. Начиная то ли с D6, то ли с D7 реализовано через события (CreateEvent если не ошибаюсь)...
Хотя смысл от этого не меняется


 
jack128 ©   (2004-12-02 23:38) [10]

можно и так, но без разницы.  Так получилось, что Suspend совпадает по сигнатуре с TThreadMethod, просто я обратил на это внимание уже после того, как написал SyncProc.


 
Игорь Шевченко ©   (2004-12-03 00:14) [11]


> Или все таки есть функция OpenThread?


Есть.


 
Digitman ©   (2004-12-03 08:52) [12]


> Alexander Panov ©   (02.12.04 22:31) [7]
> >all
> Synchronize выполняется в контексте основного потока,


необязательно в контексте основного.
это частный случай.
в общем же случае метод, переданный параметром при вызове проц-ры Synchronize, будет выполнен в контексте того трэда, который инициализировал переменную MainThreadId в ходе иниц-ции модуля System. Но для этого трэд, в контексте которого д.б. выполнен синхронизируемый метод, должен предусматривать цикл либо ожидания/выборки/диспетчеризации сообщений (и обрабатывать CM_EXECPROC в случае Д5), либо любой иной цикл, в котором происходит периодический вызов CheckSynchronize (для последующих версий Делфи)


 
Priest   (2004-12-03 09:57) [13]

Когда я задавал вопрос, я имел ввиду, что есть основной поток, в нём запускается дочерний поток. Дочерний поток заходит в метод, который вызывается в процедуре Synchronize. В этот момент главный поток пытается остановить (с помощью Suspend) дочерний поток. Я хотел узнать не повиснет ли система.


 
Priest   (2004-12-03 10:11) [14]

Разобрался. Тестировал на следующем примере
type
 TForm1 = class(TForm)
   Button1: TButton;
   procedure Button1Click(Sender: TObject);
 private
   { Private declarations }
 public
   { Public declarations }
 end;

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

var
 Form1: TForm1;
 Test:TTest;
implementation

procedure TTest.Execute;
begin
Self.Synchronize(SyncProc);
end;

procedure TTest.SyncProc;
var
i:Integer;
begin
for I := 0 to 9 do
 begin
 Form1.Caption:=IntToStr(StrToInt(Form1.Caption)+1);
 Sleep(500);
 end;
end;

procedure TForm1.Button1Click(Sender: TObject);
begin
Form1.Caption:="0";
Test:=TTest.Create(True);
with Test do
begin
  FreeOnTerminate := True;
  Resume;
end;
//Останавливаем основной поток, без этого дочерний не создавался
sleep(200);
//Срабатывает без проблем
Test.Suspend;
//Останавливается до тех пор пока не закончит выполняться SyncProc
Close;
end;


 
Priest   (2004-12-03 10:15) [15]

Интересно наблюдать за происходящим в окне ThreadStatus. Получается следующее. После запуска дочернего потока, он заходит сразу же в метод SyncProc. Сразу же в основном потоке сработает строчка Test.Suspend. Метод SyncProc работает в основном потоке, поэтому метод Close дожидается окончания SyncProc.


 
Суслик ©   (2004-12-03 13:26) [16]

да, не прав был, прошу прощения.

Еще раз убедился в качестве кода борландовцев:

Самое тонкое место в коде TThread.Synchronize
это
       LeaveCriticalSection(ThreadLock);
       try
         WaitForSingleObject(SyncProc.Signal, INFINITE);
       finally
         EnterCriticalSection(ThreadLock);
       end;


Если бы не было временного выхода из крит. секции, то нельзя было бы создать ни одного нового потока :))

Молодцы!

ЗЫ Дельфи 6, сп2


 
Piter ©   (2004-12-03 20:26) [17]

Игорь Шевченко ©   (03.12.04 0:14) [11]
Есть.


а почему она не описана в Дельфи не знаете?


 
Alexander Panov ©   (2004-12-03 20:35) [18]

Piter ©   (03.12.04 20:26) [17]
а почему она не описана в Дельфи не знаете?


Она в Help WindowsSDK упоминается. А полностью только в MSDN.



Страницы: 1 вся ветка

Текущий архив: 2005.01.23;
Скачать: CL | DM;

Наверх




Память: 0.52 MB
Время: 0.058 c
1-1105042555
pika
2005-01-06 23:15
2005.01.23
Перекрывание !!!


14-1104476437
КаПиБаРа
2004-12-31 10:00
2005.01.23
Кто чем занимается перед новым годом?


1-1105430239
Раптон
2005-01-11 10:57
2005.01.23
Как вывести поверх картинки TLabel?


1-1104962459
dmk
2005-01-06 01:00
2005.01.23
Как узнать, что мое окно находится над другим?


14-1104917688
asdqwer
2005-01-05 12:34
2005.01.23
Реализация длинной арифметики на Паскале и с делением!