Форум: "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.041 c