Главная страница
    Top.Mail.Ru    Яндекс.Метрика
Форум: "WinAPI";
Текущий архив: 2005.01.23;
Скачать: [xml.tar.bz2];

Вниз

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

 
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 вся ветка

Форум: "WinAPI";
Текущий архив: 2005.01.23;
Скачать: [xml.tar.bz2];

Наверх





Память: 0.49 MB
Время: 0.06 c
3-1103404096
Shamansky
2004-12-19 00:08
2005.01.23
Как совместить Dbgrid и dbcheckbox


1-1105049911
pika
2005-01-07 01:18
2005.01.23
Кнопочки


9-1097696674
rydmi
2004-10-13 23:44
2005.01.23
Вращение спрайтов


1-1104727124
DDDeN
2005-01-03 07:38
2005.01.23
Среда разработки в PE заголовке


14-1105111706
Programming_GOD
2005-01-07 18:28
2005.01.23
Где можно получить сертификацию Delphi





Afrikaans Albanian Arabic Armenian Azerbaijani Basque Belarusian Bulgarian Catalan Chinese (Simplified) Chinese (Traditional) Croatian Czech Danish Dutch English Estonian Filipino Finnish French
Galician Georgian German Greek Haitian Creole Hebrew Hindi Hungarian Icelandic Indonesian Irish Italian Japanese Korean Latvian Lithuanian Macedonian Malay Maltese Norwegian
Persian Polish Portuguese Romanian Russian Serbian Slovak Slovenian Spanish Swahili Swedish Thai Turkish Ukrainian Urdu Vietnamese Welsh Yiddish Bengali Bosnian
Cebuano Esperanto Gujarati Hausa Hmong Igbo Javanese Kannada Khmer Lao Latin Maori Marathi Mongolian Nepali Punjabi Somali Tamil Telugu Yoruba
Zulu
Английский Французский Немецкий Итальянский Португальский Русский Испанский