Top.Mail.Ru
Мастера DELPHI, Delphi programming community Титульная страница Поиск, карта сайта Написать письмо 
| Новости | Поиск | FAQ | Статьи | Книги | Новости VCL |
| Форумы ЧАТ | Орешник | KOL и MCK |
Форумы -» Основная («Начинающим»)/ Базы / WinAPI / Компоненты / Сети / Media / Игры / Corba и COM / KOL / FreePascal / .Net / Прочее / RSDN.ORG

« предыдущая ветвь | форум | следующая ветвь »

Как проверить успешно ли начался "процесс" в другом потоке? [WinXP]


Страницы:   1 2

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.


Страницы:   1 2

Наверх

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