![]() |
| ||
|
|
Новости |
Поиск |
FAQ |
Статьи |
Книги |
Новости VCL
| | Форумы ЧАТ |
Орешник |
|
| |||
| |||
« предыдущая ветвь | форум | следующая ветвь »
Как проверить успешно ли начался "процесс" в другом потоке? [WinXP]
Ruzzz © (2009-08-21 02:29:00)В отдельном потоке создаю слушающий сокет, хотелось бы чтобы функция, которая запускает этот поток могла вернуть True/False в зависимости от успешности Bind(Host, Port) этого слушающего сокета. Сейчас использую таймер, проверяющий свойство класса потока, которое устанавливается в Execute. Но мне не нравится это решение. Создавать сокет в главном потоке тоже не хочется, пишу код без привязки к конкретной реализации сокетов, вдруг какая-либо "сокетная" библиотека будет зависеть от этого, например использовать очередь потока. Помогите решить!
Поместил не в "Сети", потому что показалось что вопрос больше не в сетях, а в потоках :)
Leonid Troyanovsky (2009-08-25 18:44:00) [1]
> Ruzzz (25.08.09 17:33) [30]
Гм.. Пришлось добывать доказательства для PostMessage другим путем:
type
TMyThread = class (TThread)
public
e: THandle;
procedure Execute; override;
end;
procedure TMyThread.Execute;
begin
// PostThreadMessage(MainThreadId, 0, 0, 0);
// PostMessage(Application.MainForm.Handle, 0, 0, 0);
SetEvent(e);
Sleep(10000);
end;
procedure TForm1.Button1Click(Sender: TObject);
begin
with TMythread.Create(True) do
begin
e := CreateEvent(nil, False, False, nil);
Resume;
WaitForSingleObject(e, INFINITE);
Win32Check(PostThreadMessage(ThreadId, WM_NULL, 0, 0));
Free;
end;
end;
---------------------------
Debugger Exception Notification
---------------------------
Project Project1.exe raised exception class EOSError with message 'System Error. Code: 1444.
Неверный идентификатор потока команд'. Process stopped. Use Step or Run to continue.
---------------------------
OK Help
---------------------------
Но, IsGUIThread(True), сволочь, не работает в XP, похоже просто заглушка.
--
Regards, LVT.
Leonid Troyanovsky (2009-08-25 18:20:00) [2]
> Ruzzz (25.08.09 17:33) [30]
> Turbo Delphi, Win XP SP3
Да, на XP SP3 у меня тоже IsGUIThread всегда True (as 0x1).
Видимо, ms накосячили в XP, бо на 2003 server она работает.
Пробовал на D6.
--
Regards, LVT.
Ruzzz (2009-08-25 17:33:00) [3]Turbo Delphi, Win XP SP3, IsGUIThread(False) - всегда выдает что это GUI-поток
Leonid Troyanovsky (2009-08-25 10:20:00) [4]
> Ruzzz (25.08.09 09:57) [27]
> что если использовать класс TThread, то Delphi создает GUI-
> поток чтоли? Обрыл TThread, вроде ничего не нашел. Чудеса
IsGUIThread начиная с XP.
А дельфи какая?
Кста, не cdecl but stdcall.
--
Regards, LVT.
Ruzzz (2009-08-25 10:05:00) [5]Ошибся, нужно IsGUIThread(False), но результат не изменился :)
http://pic.ipicture.ru/uploads/090825/RvrQ5ES4Pv.png
Ruzzz (2009-08-25 09:57:00) [6]Спасибо за пример! У меня в результате запуска кода с закомментированными строками, поток оказывается GUI-потоком. Т.е. получается что если использовать класс TThread, то Delphi создает GUI-поток чтоли? Обрыл TThread, вроде ничего не нашел. Чудеса )
Но даже такой код:
function ThreadFunc(Parameter: Pointer): DWORD; cdecl;
begin
if IsGUIThread(True) then MessageBox(0, 'GUI', 'GUI or not GUI', 0);
end;
procedure TForm3.Button3Click(Sender: TObject);
var
lpThreadId: DWORD;
begin
CreateThread(nil, 0, @ThreadFunc, nil, 0, lpThreadId);
end;
Говорит что это GUI-поток. Странно это :)
Leonid Troyanovsky (2009-08-25 08:55:00) [7]
> Ruzzz (24.08.09 22:57) [25]
> Leonid Troyanovsky :) ну хорошо, т.е. можно точно утверждать
> что все функции из user32.dll & gdi32.dll создают из потока
> - GUI-поток?
Насчет всех зуб не дам, бо есть, например, такая функция:
function IsGUIThread(bConvert: BOOL):BOOL; stdcall;
external user32 name 'IsGUIThread';
которая осуществляет превращение лишь по требованию.
> Просто мне кажется что это бессмысленно для PostMessage
> или PostThreadMessage, поток вызывающий эти функции вполне
> может быть и не GUI-поток. Или я не прав?
Поставим смелый эксперимент:
type
TMyThread = class (TThread)
public
procedure Execute; override;
end;
procedure TMyThread.Execute;
begin
// IsGUIThread(True);
// PostThreadMessage(MainThreadId, WM_NULL, 0, 0);
// PostMessage(Application.MainForm.Handle, WM_NULL, 0, 0);
if IsGUIThread(False) then
MessageBox(0, 'GUI', 'GUI or not GUI', 0);
end;
procedure TForm1.Button1Click(Sender: TObject);
begin
TMythread.Create(False);
end;
И.. о чудо!
Легким движение руки шорты превращаются .. в элегантные брюки.
Насчет смысла можно сказать, что, например, для SendMessage
потоку уж точно потребуется очередь.
--
Regards, LVT.
Ruzzz (2009-08-24 22:57:00) [8]Leonid Troyanovsky :) ну хорошо, т.е. можно точно утверждать что все функции из user32.dll & gdi32.dll создают из потока - GUI-поток? Просто мне кажется что это бессмысленно для PostMessage или PostThreadMessage, поток вызывающий эти функции вполне может быть и не GUI-поток. Или я не прав?
Leonid Troyanovsky (2009-08-24 22:17:00) [9]
> Ruzzz (24.08.09 20:31) [23]
> Я так и не нашел где написано
[21]
Кхм.. PostMessage или PostThreadMessage
Minimum DLL Version user32.dll
--
Regards, LVT.
Ruzzz (2009-08-24 20:31:00) [10]Я так и не нашел где написано, что поток КОТОРЫЙ ВЫЗЫВАЕТ PostMessage или PostThreadMessage (т.е. функции не требующих очередь возвращенных результатов) становится GUI-потокам.
Leonid Troyanovsky (2009-08-24 07:42:00) [11]
> Сергей М. © (22.08.09 18:51) [18]
> Сейчас тебя поколотят за:
3. procedure thread; stdcall;
> VladimirVB (22.08.09 18:45) [17]
function ThreadProc(lpParameter: Pointer): DWORD; stdcall;
Кста, Write/Ln - потоконебезопасная функция.
--
Regards, LVT.
Leonid Troyanovsky (2009-08-24 07:33:00) [12]
> Ruzzz (22.08.09 18:37) [15]
> Leonid Troyanovsky, не могли бы ткнуть ссылкой где подробнее
> узнать о «PostMessage - Такой вызов сделает из потока GUI
http://msdn.microsoft.com/en-us/library/ms644946(VS.85).aspx
The system creates a thread's message queue when the thread makes its first
call to one of the User or GDI functions.
> Ruzzz (22.08.09 18:56) [19]
> jpg - осталось узнать список этих самых функций
Можно посмотреть импорты user32.dll & gdi32.dll путем tdump.exe
--
Regards, LVT.
Сергей М. (2009-08-22 22:28:00) [13]
> узнать список этих самых функций
Достаточно двух - GetMessage и PeekMessage
Ruzzz (2009-08-22 18:56:00) [14]поспешил :) нашел вот еще: http://pic.ipicture.ru/uploads/090822/CH0Y5ps7U8.jpg- осталось узнать список этих самых функций
Сергей М. (2009-08-22 18:51:00) [15]
> VladimirVB (22.08.09 18:45) [17]
Сейчас тебя поколотят за:
1. Пример, не имеющий отношения к проблеме автора.
2. Пример, ведущий к заблуждениям в отношении CreateThread vs BeginThread
VladimirVB (2009-08-22 18:45:00) [16]При помощи функции WaitForSingleObject
Попробуй такой пример
program Project1;
{$APPTYPE CONSOLE}
uses
SysUtils,
Windows;
var
hThread: HWND;
IDThread: DWORD;
procedure thread; stdcall;
var
i: Integer;
begin
for i := 0 to 9 do
begin
Write(i, ' ');
Sleep(100);
end;
Writeln;
end;
begin
hThread := CreateThread(nil, 0, @thread, nil, 0, IDThread);
if hThread = 0 then
Halt(GetLastError);
// ждем завершения потока thread
if WaitForSingleObject(hThread, INFINITE) <> WAIT_OBJECT_0 then
begin
Writeln('Wait for single object failed.');
Writeln('Press any key to exit.');
Readln;
end;
//закрываем дескриптор потока
CloseHandle(hThread);
Write('Press any key to exit.');
Readln;
end.
Ruzzz (2009-08-22 18:41:00) [17]Да и у того же Рихтера говорится, что из рабочего в GUI поток «превращается» только после создания окна.
Ruzzz (2009-08-22 18:37:00) [18]Leonid Troyanovsky, не могли бы ткнуть ссылкой где подробнее узнать о «PostMessage - Такой вызов сделает из потока GUI thread.»?
Вот у Рихтера нашел (стр 649-650), GUI поток имеет дополнительно THREADINFO тут есть очереди сообщений, PostMessage - это ассинх. посылка и не возвращает результат обработки сообщения оконной функцией (возвращает только True/False - успешность операции). Поэтому после ее выполнения, потоку не нужно создавать очередь ответных сообщений? Так или нет? То есть по идее PostMessage не делает GUI thread?
Вариант (2009-08-21 14:16:00) [19]
> Если б можно было возможность всунуть туда вместо
> WaitMessage тот же MsgWaitForMultipleObjectsEx оно б пошло
> приложению только на пользу
MsgWaitForMultipleObjectsEx - возможность то есть в своем коде это сделать, только код это несколько усложняет (хотя и не сильно, но выглядит немного извращением) и есть еще одно для меня
> Для рабочего потока (рабочей лошадки) все это илишества.
- тут спорить не буду - есть такое, но просто мне нравится простой способ сигнализации с возможностью передачи и дополнительных параметров - это я о PostMessage или о PostThreadMessage.
Спасибо за ответ.
Leonid Troyanovsky (2009-08-21 13:39:00) [20]
> Вариант (21.08.09 11:16) [12]
> - сделает GUI thread - если можно -что это означает для
> потока вызвашего PostMessage, для посылки сообщения например
> главному окну? user32?
В изначально созданном потоке нет a thread's message queue,
она создается при первом обращении к User or GDI функциям.
Думаю, что это не одна структура, отличающая GUI поток
от work thread, если, например, вспомнить, что окна, хуки,
таблицы акселераторов являются собственностью потока,
и, сл-но, их описания где-то в ем (объекте ядра) хранятся.
> И второй вопрос - Это плохо? Borland до дельфи 5 включительно
> для Synchronize использовал SendMessage. И если это сделает
> GUI Thread - мне кажется это допустимо, ибо другие варианты
> сложнее для реализации
Не знаю, плохо или нет.
Для рабочего потока (рабочей лошадки) все это илишества.
Насчет SendMessage - они переделали лишь потому, что
в некоторых случаях он приводил к deadlock.
Ну, и еще, наверное, что целились в линукс.
Сложность реализации борланды сами задали кривизной TApplication
(впрочем, и нек. других классов, скажем, TScreen и т.д.), например,
в районе Idle. Если б можно было возможность всунуть туда вместо
WaitMessage тот же MsgWaitForMultipleObjectsEx оно б пошло
приложению только на пользу.
--
Regards, LVT.