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

Вниз

Много ли отнимает ресурсов системы нить...   Найти похожие ветки 

 
GuAV ©   (2007-02-18 01:22) [0]

...с очередью сообщений и ожиданием MsgWaitForMultipleObjects?
Намного ли больше чем такая же нить, но без очереди сообщений и с WaitForMultipleObjects?
Много ли дополнительно ресурсов потребуется, если нить с очередью создаст невидимое окно для своих сообщений?


 
Leonid Troyanovsky ©   (2007-02-18 11:46) [1]


> GuAV ©   (18.02.07 01:22)  

> ...с очередью сообщений и ожиданием MsgWaitForMultipleObjects?
>
> Намного ли больше чем такая же нить, но без очереди сообщений
> и с WaitForMultipleObjects?
> Много ли дополнительно ресурсов потребуется, если нить с
> очередью создаст невидимое окно для своих сообщений?

Думаю, что для GUI application весь этот overhead практически
незаметен. Т.е., об этом можно б было задуматься, если снабжать
таким потоком консольное приложение. Или создавать
сотни подобных потоков.

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

--
Regards, LVT.


 
guav ©   (2007-02-18 14:01) [2]

> Т.е., об этом можно б было задуматься, если снабжать
> таким потоком консольное приложение. Или создавать
> сотни подобных потоков.


Вот такой случай. Ну не сотни, но несколько десятков быть может.
GUI поток имеется, обычно всё время спит, т.к. приложение свёрнуто.
Дело в том, что имеется многопоточное приложение с блокирующими сокетами (ожидание везде через select), что-то вроде порт-маппинга, иногда изменяющего данные. Требуется сделать, чтобы в потоках соединений ожидание было не только сокета, но и других событий. Удобнее всего было бы сделать цикл GetMessage и асинхронные сокеты с WSAAsyncSelect, но тогда придется создать очередь сообщений и окно, не многовато ли ? Если большой дополнительный оверхед добавляет именно окно, можно было бы сделать сокеты на событиях и цикл MsgWaitForMultipleObjects. можно вообще без очереди сообщений сделать, дополнительные события тогда будут тоже объектами event. Есть вообще мысль перенести все сервера и их соединения в 1-2 доп. потоков, или даже в GUI поток, но не снизит ли это производительности сервера ?


 
Leonid Troyanovsky ©   (2007-02-18 14:26) [3]


> guav ©   (18.02.07 14:01) [2]

> > сотни подобных потоков.

> Вот такой случай. Ну не сотни, но несколько десятков быть
> может.


Критическим значением, видимо, следует признать 64 - ограничение
на WaitFor. Следующим критерием - кол-во процессоров на целевой
машине, и насколько часто требуется переключение контекстов.

На rsdn есть статья о использовании пула потоков
Эффективная многопоточность (must have).

Кстати, где-то там было обсуждение оптимальности различных
схем, и общественность склонилась к использованию портов
завершения ввода/вывода. Хотя, честно говоря, я не очень
уверен, что оно было применительно к сокетам и т.п.

Кроме того, если задумываться об оптимальности, то
стоило б поразмышлять об использовании сервисов
и полностью отказаться от GUI.
В этом случае приложение не будет отвлекаться на обработку
всяких бродкастов.

--
Regards, LVT.


 
guav ©   (2007-02-18 16:36) [4]

Пул потоков - да, это дейсвительно оптимальный вариант ограничить оверхед на многопоточность, если одного-двух потоков не хватит. Уже читаю статью.
Что касается переключении контекстов, то тут или только один реально рабочий поток или они таки будут переключатся, не так ли ?


> общественность склонилась к использованию портов
> завершения ввода/вывода.

Этот вариант я не рассматривал, т.к. мне пока не совсем понятна работа overlapped вообще и сокетов в частности.

> Кроме того, если задумываться об оптимальности, то
> стоило б поразмышлять об использовании сервисов
> и полностью отказаться от GUI.
> В этом случае приложение не будет отвлекаться на обработку
> всяких бродкастов.

Хм. В потоке чтобы не получать бродкастов вроде достаточно не создавать окон, или создавать только child окна. Необходимости создания сервиса в моём случае не вижу.

Вот ещё вопрос, уже про сокеты: можно ли содать сокет без привязки к TCP/IP и вообще к сети, просто для обмена внутри приложения, чтобы ожидать его в том же select что и другие ?


 
Leonid Troyanovsky ©   (2007-02-18 16:49) [5]


> guav ©   (18.02.07 16:36) [4]

> Что касается переключении контекстов, то тут или только
> один реально рабочий поток или они таки будут переключатся,

Они ж переключатся, если дождуться своего WaitFor.
Вопрос лишь в том, насколько это часто.
Можно представить поток, который будет всю жизнь
приложения сидит в WaitFor, и, сл-но, никаких излишеств
себе не позволяет.

> Этот вариант я не рассматривал, т.к. мне пока не совсем
> понятна работа overlapped вообще и сокетов в частности.

Не overlapped, а именно портов, т.е., то, что c WaitFor..Ex.

> Хм. В потоке чтобы не получать бродкастов вроде достаточно
> не создавать окон, или создавать только child окна. Необходимости

Скажем, окон верхнего уровня. Тех же AllocateHwnd.

> Вот ещё вопрос, уже про сокеты: можно ли содать сокет без
> привязки к TCP/IP и вообще к сети, просто для обмена внутри
> приложения, чтобы ожидать его в том же select что и другие

ХЗ. Сокеты могли быть и на IPX, IMHO. Только где он сейчас?

С другой стороны, для обмена внутри приложения можно
придумать и более эффективное. Даже если в пределах
сессии, рабочего стола.

--
Regards, LVT.


 
guav ©   (2007-02-18 17:53) [6]

> ХЗ. Сокеты могли быть и на IPX, IMHO. Только где он сейчас?

AFAIK, можно и сейчас установить и использовать IPX.
У меня WSAEnumProtocols возвращает только TCP, UDP с AF_INET и ещё какие-то с AF_NETBIOS
Но вот в WinSock есть такая AF_ константа:
 AF_UNIX         = 1;               { local to host (pipes, portals) }
Интересно, можно ли напрямую создать пару таких сокетов ?
Что касается анонимных пайпов, сообщений, событий и других средств синхронизации, то их общий недостаток такой, что их нельзя передать в обычный select, что вынуждает отказатся от обычных блокирующих сокетов.


> Не overlapped, а именно портов, т.е., то, что c WaitFor..Ex.

Да, я уже понял, пытаюсь разобратся в статье http://www.rsdn.ru/article/baseserv/threadpool.xml


 
homm ©   (2007-02-18 18:11) [7]

> AFAIK, можно и сейчас установить и использовать IPX.
В 64-х битных осях нет больше IPX Afaik


 
DiamondShark ©   (2007-02-19 15:32) [8]


> но тогда придется создать очередь сообщений и окно

окно не нужно


 
guav ©   (2007-02-19 16:36) [9]

> [8] DiamondShark ©   (19.02.07 15:32)


> окно не нужно

Если вы про ненужность окна в режиме WSAAsyncSelect, то я не знаю как тут обойтись без окна.
Несмотря на то, что сообщения сокета отправляются асинхронно (т.е. GetMessage их возращает, а не направляет в оконную процедуру), попытка вызвать WSAAsyncSelect с нулём вместо окна или для несуществующего окна приводит к ошибке 10022 = WSAEINVAL, "Invalid argument." .
Не исключаю что я делаю что-то не так, или что WSAAsyncSelect без окна работает в некоторых реализациях WinSock, а в некоторых - нет.

Для других режимов работы сокетов, разумеется, не нужны ни окно, ни очередь сообщений.


 
guav ©   (2007-02-19 17:01) [10]

> [9] guav ©   (19.02.07 16:36)

Вот так можно я получаю ошибку при WSAAsyncSelect без окна
uses WinSock;
//uses JwaWinSock2;

var
 Data: TWSAData;
 WSAInitResult: Integer = WSANOTINITIALISED;

procedure Check(Result: Integer; const Condition: string);
begin
 if Result <> SOCKET_ERROR then
   Exit;
 Result := WSAGetLastError;
 if Condition = "" then
   raise Exception.CreateFmt("Ошибка %d.", [Result])
 else
   raise Exception.CreateFmt("Ошибка %d %s", [Result, Condition]);
end;

function InitializeServerSocket: TSocket;
var
 Addr: TSockAddrIn;
 SockResult: Integer;
const
 LocalPort = 7070;
begin
 Check(WSAInitResult, " инициализации библиотеки.");

 Result := socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
 Check(Result, " при инициализации.");

 try
   with Addr do
   begin
     sin_family := AF_INET;
     sin_port := htons(LocalPort);
     sin_addr.S_addr := inet_addr("127.0.0.1");
     ZeroMemory(@sin_zero, SizeOf(sin_zero));
   end;
   SockResult := bind(Result, Addr, SizeOf(Addr));
   Check(SockResult, " при привязке к адресу");

   SockResult := listen(Result, SOMAXCONN);
   Check(SockResult, " при переходе в режим ожидания");

   SockResult := WSAAsyncSelect(Result, 0 {Application.Handle}
     ,WM_USER, FD_ACCEPT or FD_READ or FD_CLOSE);
   Check(SockResult, " при переходе в асинхронный режим");
 except
   closesocket(Result);
   raise;
 end;
end;

procedure TForm1.FormCreate(Sender: TObject);
begin
 WSAInitResult := WSAStartup($002, Data);
end;

procedure TForm1.Button1Click(Sender: TObject);
begin
 CloseSocket(InitializeServerSocket);
end;

procedure TForm1.FormDestroy(Sender: TObject);
begin
 WSACleanup;
end;


 
Сергей М. ©   (2007-02-19 17:09) [11]


> guav ©   (19.02.07 17:01) [10]


Без окна в случае с WSAAsyncSelect, разумеется, не обойтись.
Но ничто не мешает при этом использовать окно любого другого потока, в т.ч. основного.

Извещения о трансп.событиях будут посылаться в очередь оконных сообщений потока, создавшего это окно.


> WM_USER, FD_ACCEPT or FD_READ or FD_CLOSE


из всего вышеперечисленного слушающему гнезду нужны только FD_ACCEPT и FD_CLOSE.

А WM_USER к WSAAsyncSelect/WSAEventSelect вообще не имеет никакого отношения.


 
guav ©   (2007-02-19 17:26) [12]

> из всего вышеперечисленного слушающему гнезду нужны только
> FD_ACCEPT и FD_CLOSE.

FD_READ для того чтобы этот режим унаследовал сокет соединения.
WM_USER - это просто произвольный номер сообщения связанного с сокетом.


> Но ничто не мешает при этом использовать окно любого другого
> потока, в т.ч. основного.
>
> Извещения о трансп.событиях будут посылаться в очередь оконных
> сообщений потока, создавшего это окно.

Ну да, то есть или дополнительный поток создаёт окно или он не получает сообщения, и, следовательно, не нужен.

Разумеется можно пересылать сообщения из основного потока дополнительным, но этот вариант кажется ещё хуже, чем создание лишних окон, здесь излишнее переключение контекстов, зависимость от основного потока и усложнение кода.

PS: Пока я ещё никак не делал, так что советы давать ещё не поздно.


 
Сергей М. ©   (2007-02-19 17:39) [13]


> FD_READ для того чтобы этот режим унаследовал сокет соединения


А почему тогда FD_WRITE не  указываешь ? Или оно не потребуется ?


> WM_USER - это просто произвольный номер сообщения связанного
> с сокетом.
>


А, ну да, все правильно.
Я его почему-то к маске событий отнес.

Ну а почему WSAEventSelect не задействовать, коль окна смущают ?


 
guav ©   (2007-02-19 19:46) [14]

> А почему тогда FD_WRITE не  указываешь ? Или оно не потребуется ?

Да, надо указать и FD_WRITE. Однако, во временном пробном варианте можно и не указать, и вызывать send когда вздумается, я читал что при send при стандартных размерах буферов WSAEWOULDBLOCK получается редко.


> Ну а почему WSAEventSelect не задействовать, коль окна смущают ?

Этот вариант показался мне несколько сложнее.
Вопрос в [0] так и поставлен - много ли оверхеда у окон по сравнению с событиями ?

Ещё вопрос - можно ли привязать несколько сокетов к одному событию ?


 
Leonid Troyanovsky ©   (2007-02-20 00:33) [15]


> guav ©   (19.02.07 19:46) [14]

> Вопрос в [0] так и поставлен - много ли оверхеда у окон
> по сравнению с событиями ?

Ты бы,все ж, рассказал,что там с портами, бо, оверхед,
в сравнении с ними, немерянный.

--
Regards, LVT.


 
guav ©   (2007-02-20 12:06) [16]

> Ты бы,все ж, рассказал,что там с портами, бо, оверхед,
> в сравнении с ними, немерянный.

Рассказываю:

Создаются локальные сервера, несколько штук. Когда к локальному серверу подключается клиент, происходит соединение с удалённым сервером. Данные удалённого сервера перенаправляются локальному клиенту, и наоборот, при этом данные просматриваются, и иногда меняются. Соединения существуют длительное время.
Что нужно добавить: другой тип серверов, обслуживающий уже кратковременные соединения и в большем количестве. Также добавить отправку данных по своей инициативе.
Все соединения TCP. Данные - (почти) текст.


 
Сергей М. ©   (2007-02-20 13:46) [17]


> Этот вариант показался мне несколько сложнее


Да нет там ничего сложного.


> можно ли привязать несколько сокетов к одному событию ?


Как это так ?

Сокеты не привязываются к событиям. События происходят в сокетах, хочешь ты того или не хочешь.

Вызовами WSAAsync/EventSelect с указанием одного или нескольких флагов событий (маски) ты всего лишь указываешь, какие события тебя интересуют, т.е. о каких событиях в указанном гнезде ты хочешь получать извещения в том или ином виде (Async - в виде оконных сообщений указанному окну, Event - в виде сигналов указанного event-объекта)

Если же под "к одному событию" тобой подразумевается тот самый event-объект, то да, можно, но это ощутимо усложняет алгоритм реакции на сигнал единственного event-объекта, который будет сигналить при любом событии в любом из ассоциированных с ним сокетах. Т.е. обнаружение сигналящего состояния такого event-объекта можно расценивать лишь как факт произошедших (одного или более) событий в одном или более сокетах. Какие события в каких сокетах - об этом event-объект сообщить не может, для этого потребуется вызывать WSAEnumNetworkEvents для каждого из сокетов, которые ранее были ассоциированы с этим event-объектом.



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

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

Наверх




Память: 0.52 MB
Время: 0.043 c
11-1166973414
mixail_shar
2006-12-24 18:16
2007.08.05
MCK


6-1166780950
DeadMeat
2006-12-22 12:49
2007.08.05
ICS - проблема дисконнекта


1-1179996867
Tonich
2007-05-24 12:54
2007.08.05
Вызов функции из dll


15-1181944148
Kostafey
2007-06-16 01:49
2007.08.05
Спасибо Вам за то что Вы есть !


3-1177408993
DROWSYS
2007-04-24 14:03
2007.08.05
BDEADMIN.exe





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
Английский Французский Немецкий Итальянский Португальский Русский Испанский