Перейти из форума на сайт.

НовостиФайловые архивы
ПоискАктивные темыТоп лист
ПравилаКто в on-line?
Вход Забыли пароль? Первый раз на этом сайте? Регистрация
Компьютерный форум Ru.Board » Компьютеры » Прикладное программирование » VC++: асинхронные события

Модерирует : ShIvADeSt

 Версия для печати • ПодписатьсяДобавить в закладки
Страницы: 1 2

Открыть новую тему     Написать ответ в эту тему

mymuss



Advanced Member
Редактировать | Профиль | Сообщение | ICQ | Цитировать | Сообщить модератору
Привет!
 
Ситуация: есть прога на VC++, в ней 2 потока:
 - интерфейс
 - worker thread для общения с сервером по сети
Последний постоянно ждет от сервера чего-то, т.е. recv() в бесконечном цикле.
 
Предположим юзер нажимает кнопку и после этого нужно прекратить цикл. Вопрос: как это сделать?
 
Можно постоянно делать опрос при помощи select() или сделать неблокируемый сокет. Но хочется чего-то более элегантного. В *никсе я бы просто сделал асинхронный сокет и ловил бы SIGIO. Под форточкой так, конечно, не выйдет. Что делать?
 
Спасибо.
 
Добавлено
И еще, а есть вообще в винде poll()?

----------
(a + b^n) / n = x, donc Dieu existe; répondez !
Euler

Всего записей: 709 | Зарегистр. 13-04-2003 | Отправлено: 08:20 25-08-2003
ShIvADeSt



Moderator
Редактировать | Профиль | Сообщение | Цитировать | Сообщить модератору
Используй мьютексы или семафоры. Вначале он выключен, после нажатия кнопки влючай его, а в цикле можно делать проверку на WaitForSingle.... не помню окончания. Если не понятно скажи или посмотри в Хэлпе, там есчть подробный пример по их использованию. (они как раз и предназначены для синхронизации потоков)

----------
И создал Бог женщину... Существо получилось злобное, но забавное...

Всего записей: 3956 | Зарегистр. 29-07-2003 | Отправлено: 09:16 25-08-2003
mymuss



Advanced Member
Редактировать | Профиль | Сообщение | ICQ | Цитировать | Сообщить модератору
ShIvADeSt
Не понятно. recv() же блокируется. А если делать его неблокируемым и постоянно опрашивать то тогда и семафор не нужен.

----------
(a + b^n) / n = x, donc Dieu existe; répondez !
Euler

Всего записей: 709 | Зарегистр. 13-04-2003 | Отправлено: 11:53 25-08-2003
ShIvADeSt



Moderator
Редактировать | Профиль | Сообщение | Цитировать | Сообщить модератору

Цитата:
Не понятно. recv() же блокируется.
А вот это по барабану. Семафоры и подобные объекты от этого не зависят. Они Находятся в той области памяти, которую видят ВСЕ приложения. Вот по моему то, что тебе надо.
The CreateEvent function creates a named or unnamed event object.  
 
HANDLE CreateEvent(
 
    LPSECURITY_ATTRIBUTES lpEventAttributes, // pointer to security attributes  
    BOOL bManualReset, // flag for manual-reset event  
    BOOL bInitialState, // flag for initial state  
    LPCTSTR lpName // pointer to event-object name  
   );
 
If the function succeeds, the return value is a handle to the event object. If the named event object existed before the function call, the GetLastError function returns ERROR_ALREADY_EXISTS. Otherwise, GetLastError returns zero.  
If the function fails, the return value is NULL. To get extended error information, call GetLastError.  
То есть в одном потоке, когда надо прервать цикл, создаешь Event, а во втором, при помощи  OpenEvent смотришь, если результат отличен от нуля, то Break или что тама у вас в С. Если и это не подходит, то я и не знаю, что еще надо. Так как это одна из  
The following functions are used in synchronization.  


----------
И создал Бог женщину... Существо получилось злобное, но забавное...

Всего записей: 3956 | Зарегистр. 29-07-2003 | Отправлено: 00:47 26-08-2003
OOSL

Junior Member
Редактировать | Профиль | Сообщение | Цитировать | Сообщить модератору

Цитата:
и после этого нужно прекратить цикл.  

А может просто поток убить.
 
Еще может я чего путаю, но вроде в сетевом API можно задавть таймауты,
и к сокету на что-то Event привязывать...

Всего записей: 85 | Зарегистр. 16-07-2003 | Отправлено: 11:22 26-08-2003
ShIvADeSt



Moderator
Редактировать | Профиль | Сообщение | Цитировать | Сообщить модератору
OOSL а при чем здесь сетевое АПИ. Ты же о потоках спрашивал . Я вообще не понимаю в чем проблема. Я сам писал такие проги, и все нормально работало. В общем у меня есть проект ( не мой но с исходниками на сях) он состоит из двух частей клиент и сервер. Клиент с интерфейцом посылает всякую лажу серверу, а при ответе выводит сообщение, что мессага доставлена. Причем это все при помощи TCP/IP и никаких потоков. Если надо дай мыло я сразу же пульну.


----------
И создал Бог женщину... Существо получилось злобное, но забавное...

Всего записей: 3956 | Зарегистр. 29-07-2003 | Отправлено: 01:08 27-08-2003
BugFixer

Full Member
Редактировать | Профиль | Сообщение | Цитировать | Сообщить модератору
ShIvADeSt

Цитата:
а в цикле можно делать проверку на WaitForSingle.... не помню окончания.

WaitForSingleObjectWaitForMultipleObjects)

Всего записей: 482 | Зарегистр. 02-08-2003 | Отправлено: 08:39 28-08-2003
Bloody_Nokia_Adept



Advanced Member
Редактировать | Профиль | Сообщение | Цитировать | Сообщить модератору
mymuss
При работе с WinSock2 можно использовать асинхронные сокеты и связанное с ними семейство команд WSA... Так вот там ты можешь сделать такой финт ушами: создаешь сокет по WSASocket и хендл события по WSACreateEvent, а потом вешаешь на хендл через WSAEventSelect нежные тебе события на сокете (FD_READ / FD_WRITE / FD_CONNECT / FD_CLOSE) и ждешь где-то в своем коде в вечном цикле этого события по WSAWaitForMultipleEvents. Как только что-то происходит WSAWaitForMultipleEvents возвращает исполнение твоей проге и ты по WSAEnumNetworkEvents узнаешь, какие же именно события произошли на сокете.
 
К чему все это? Кроме того ты создаешь какое-то свое событие по CreateEvent и заводишь какой-то флаг завершения выполнения. В WSAWaitForMultipleEvents подписываешься не просто на свобытие на сокете, а одновременно на их оба. Теперь ты анализируешь какое событие произошло и дальше по switch делаешь ветвление выполнения в соответствии с типом события.
 
Понятно объяснил?
 
Добавлено
Главное - мы получаем на асинхронном сокете синхронный, т.к. WSAWaitForMultipleEvents блокирует исполнение программы до момента выброса ожидаемых событий.

----------
Дядя Фёдор, пес и кот - все в одном лице живет!
Он обфукать любит сразу, вот такая вот зараза!
Эпиграмма на меня, "1001 ночь ХАИ", 535 гр., 1999 г.

Всего записей: 785 | Зарегистр. 27-11-2002 | Отправлено: 10:20 28-08-2003
EAS



Full Member
Редактировать | Профиль | Сообщение | Цитировать | Сообщить модератору
Собственно, как я себе это представляю, асинхронные сокеты + Event'ы как-раз и пытаются изобразить *nix вариант. Ну нет в Вынь сигналов, нету. Может и не надо излишних заморочек? Ведь как я понял, в *никсе рабочая нить, после recv() все-равно будет сидеть и балдеть в ожидании данных.
Как альтернативу уже перечисленному, могу предложить старый ржавый лом для убийства sync recv()- закрывать сокет нахрен. Оч.Зло. . Когда-то тоже мучился, но красивого способа свалить sync recv() в винде не нашел. В *nix -- сигналы, понятно (хочешь - SIGIO, хочешь SIGALARM... Лепота).
Хотя я сам уважаю "спортивный подход" к программированию.
 
 
Добавлено
Гы, или я торможу, или чего-то не догоняю, или...
Чем неблокируемые сокеты отличаются от асинхронных? (Кроме названия ессно)
 
Добавлено
ShIvADeSt

Цитата:
Клиент с интерфейцом посылает всякую лажу серверу, а при ответе выводит сообщение, что мессага доставлена. Причем это все при помощи TCP/IP и никаких потоков

 
Ты ето под вынь делал? Просто интересно, заимплементена ли у тебя такая фича, как эстетичное убийство всего этого дела (то есть прерывание send/recv) юзером. Без потоков то это под винды на синхронных сокетах - галяк. В *nix можно select'ом пройтись и по stdio, а вот у MS . Портировали BSD-сокеты, портировали, да не выпортировали... Улучшили и углубили , как всегда

Всего записей: 441 | Зарегистр. 18-07-2003 | Отправлено: 02:41 29-08-2003
mymuss



Advanced Member
Редактировать | Профиль | Сообщение | ICQ | Цитировать | Сообщить модератору
EAS

Цитата:
Чем неблокируемые сокеты отличаются от асинхронных?

Неблокируемые: read(), recv() итд. после вызова сразу же возвращаются, причем если сокет был готов к операции в/в, она произошла, иначе errno / WSAGetLastError() возвращает ошибку EAGAIN (*nix), WSAEAGAIN (или что-то похожее -- win).
 
Асинхронные: при помощи fcntl() на сокете (пайпе, файловом дескрипторе) ставим флаг O_ASYNC, кроме того ставим обработчик сигнала SIGIO и занимаемся чем душе угодно. Когда дескриптор вдруг становится готовым к в/в нам просигналят. Минусы: некоторые экзотические (читать: уродские) ядра не поддерживают это (или же поддерживают но не для всех типов дескрипторов).
 
Bloody_Nokia_Adept
А чем (концептуально) отличается семейство вызовов WSA...() от аналогичных без WSA?
Т.е., если я уже огромный кусок проги наваял с использованием обычных функций а-ля *никс, мне теперь надо все это переделать в стиле WSA...?

----------
(a + b^n) / n = x, donc Dieu existe; répondez !
Euler

Всего записей: 709 | Зарегистр. 13-04-2003 | Отправлено: 08:41 29-08-2003 | Исправлено: mymuss, 08:42 29-08-2003
mymuss



Advanced Member
Редактировать | Профиль | Сообщение | ICQ | Цитировать | Сообщить модератору
Bloody_Nokia_Adept

Цитата:
Понятно объяснил?  

Супер! Все заработало. Спасибо за толковое объяснение!
 
 
OOSL

Цитата:
А может просто поток убить.  

Это некрасиво в принципе, к тому же, в моем случае нужно сказать серверу напоследок типа "Сушим весла". По этой же причине нельзя:

Цитата:
закрывать сокет нахрен. Оч.Зло



----------
(a + b^n) / n = x, donc Dieu existe; répondez !
Euler

Всего записей: 709 | Зарегистр. 13-04-2003 | Отправлено: 12:07 30-08-2003 | Исправлено: mymuss, 12:07 30-08-2003
Bloody_Nokia_Adept



Advanced Member
Редактировать | Профиль | Сообщение | Цитировать | Сообщить модератору
mymuss
А я только догляделся, что ты спрашивал про разъяснение WSA функций
Я рад, что смог тебе помочь

----------
Дядя Фёдор, пес и кот - все в одном лице живет!
Он обфукать любит сразу, вот такая вот зараза!
Эпиграмма на меня, "1001 ночь ХАИ", 535 гр., 1999 г.

Всего записей: 785 | Зарегистр. 27-11-2002 | Отправлено: 12:11 30-08-2003
EAS



Full Member
Редактировать | Профиль | Сообщение | Цитировать | Сообщить модератору
mymuss
Thx, c неблокируемыми/асинхронными понял. Больше под уродское ядро (но не сказал бы что экзотическое ) програмлю, поэтому сразу такое в голову и не пришло.

Всего записей: 441 | Зарегистр. 18-07-2003 | Отправлено: 03:09 31-08-2003
mymuss



Advanced Member
Редактировать | Профиль | Сообщение | ICQ | Цитировать | Сообщить модератору
EAS

Цитата:
Больше под уродское ядро (но не сказал бы что экзотическое  ) програмлю

Если не секрет, какое?

----------
(a + b^n) / n = x, donc Dieu existe; répondez !
Euler

Всего записей: 709 | Зарегистр. 13-04-2003 | Отправлено: 13:11 31-08-2003
EAS



Full Member
Редактировать | Профиль | Сообщение | Цитировать | Сообщить модератору
mymuss

Цитата:
Если не секрет, какое?

У-у-у, большая тайна . Расскажу конечно, только ты никому не выдавай, ни-ни.
Windows, называется . Ну нет в ней сигналов, хоть ты тресни. Поэтому и асинхронных сокетов тоже нема. Event'ы, согласись, все-таки не то. Их где-нибудь, да надо ждать.
(Конечно, наверное можно что-нибудь наворотить, если взять отдельную нитку, грести в ней события и кидать прерывания или exceptions, но это :-\)

Всего записей: 441 | Зарегистр. 18-07-2003 | Отправлено: 04:45 01-09-2003
Mickey_from_nsk

Advanced Member
Редактировать | Профиль | Сообщение | Цитировать | Сообщить модератору
mymuss

Цитата:
Это некрасиво в принципе, к тому же, в моем случае нужно сказать серверу напоследок типа "Сушим весла". По этой же причине нельзя:  

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

Всего записей: 636 | Зарегистр. 21-10-2002 | Отправлено: 06:49 01-09-2003
Bloody_Nokia_Adept



Advanced Member
Редактировать | Профиль | Сообщение | Цитировать | Сообщить модератору
EAS

Цитата:
Windows


Цитата:
Ну нет в ней сигналов, хоть ты тресни. Поэтому и асинхронных сокетов тоже нема.
 
Обьясни пожалйуста связь между отсутствием сигналов и асинхронными сокетами?  
 
К твоему сведению в Windows полноценные асинхронные сокеты! Не веришь мне - спроси у mymuss. Он написал свою прогу именно на них, на асинхронных сокетах.
 

Цитата:
Event'ы, согласись, все-таки не то. Их где-нибудь, да надо ждать.

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

----------
Дядя Фёдор, пес и кот - все в одном лице живет!
Он обфукать любит сразу, вот такая вот зараза!
Эпиграмма на меня, "1001 ночь ХАИ", 535 гр., 1999 г.

Всего записей: 785 | Зарегистр. 27-11-2002 | Отправлено: 10:22 01-09-2003
mymuss



Advanced Member
Редактировать | Профиль | Сообщение | ICQ | Цитировать | Сообщить модератору
EAS

Цитата:
Ну нет в ней сигналов, хоть ты тресни. Поэтому и асинхронных сокетов тоже нема. Event'ы, согласись, все-таки не то

Ну... тут вопрос спорный. Сигналы тоже не подарочек. В частности, не гарантируется, что сигналы доставляются в порядке отправления. Когда у тебя несколько дескрипторов, нет способа различить какой именно стал готовым (без poll() / select()). С асинхронными сокетами тоже проблема есть: например, если три клиента отошлют что-то серверу, никакой гарантии что ты получишь 3 раза SIGIO.  
 
В серьезных приложениях это большая проблема. Правда, в последнее время нормальные ядра поддерживают так называемые POSIX realtime signals, но таких пока не много.
 
Добавлено
Mickey_from_nsk

Цитата:
В принципе можно сказать серверу "сушим весла" и из управляющего потока

Можно, но это плохой стиль, ПМСМ. И лишние глобальные переменные.
 
Bloody_Nokia_Adept

Цитата:
Сигналы тоже ты где-то ждешь  

Нет, не ждешь. Просто задаешь какую-то функцию при помощи sigaction() и она будет вызвана при поступлении сигнала. А события выходит все же жду: WSAWaitForMultipleEvents().

----------
(a + b^n) / n = x, donc Dieu existe; répondez !
Euler

Всего записей: 709 | Зарегистр. 13-04-2003 | Отправлено: 17:25 01-09-2003
EAS



Full Member
Редактировать | Профиль | Сообщение | Цитировать | Сообщить модератору

Цитата:
Обьясни пожалйуста связь между отсутствием сигналов и асинхронными сокетами

Ну, не сетевик я, писал конечно кой-чего и в универе и для души под сетки на уровне сокетов, на учебно/любительском уровне, не более того. И под Win, и под *них (даже портабельное довелось когда-то генерить, т.е. где скомпилишь, там и пашет). Так что,  уж как понял пояснения mymuss. Помнится там, у_них, после обработки сигнала получаем заодно выход из текущей функции (ГЫ: не знаток я nix'a, остаточные воспоминания преимущественно).
Если возникает такой вопрос, то может я все-таки неправильно разницу между async/nonblocking понимаю (нету сейчас мана под рукой к сожалению, иначе, думаю, сам бы разобрался, коли уж дело зашло; полезно было бы). Как себе представляю (и как ~знаю), в Win, nonblock как раз на Event'ах завязаны. А вот что есть async socket в Винде тогда -- не впираю. Или я путаю?  
Т.е. если nonblock то сидим и ждем когда по сети прокачает что надо (в цикле что-ли !? Имхо это как-то несурьезно)?, а когда async ждем event, так что-ли получается?  
Видать требуется обращение за более подробным разъяснением (с демо-куском кода, например) к
Цитата:
mymuss. Он написал свою прогу именно на них, на асинхронных сокетах

Т.е Q. is в чем и как различается идейно работа с async/nblock sockets в вынь/у_них.

Цитата:
Сигналы тоже ты где-то ждешь или по крайней мере отводишь куски кода для их обработки

Плавали чуток, знаем капельку. Опять-таки, код ядра детально не изучал, но как себе это представляю, установка обработчика сигнала примерно есть установка вектора прерывания => сигналы, как и сказал выше mymuss, нигде специально не ждутся (если, конечно, sleep или что-нибудь подобное не плюхнуть).
 
Чувствую, без комментариев mymuss, как знатока *nix и проведшего аналогию с Win, не обойтись...
 
Добавлено
А с отсутствием сигналов -- как понял, асинхронность и получается за счет асинхронности обработки сигналов SIGIO. Так как подобного в Win нет (аналогичной  асинхронной схемы оповещений, скажем так), то и с асинхронностью загвоздка получается.

Всего записей: 441 | Зарегистр. 18-07-2003 | Отправлено: 02:50 02-09-2003 | Исправлено: EAS, 03:04 02-09-2003
mymuss



Advanced Member
Редактировать | Профиль | Сообщение | ICQ | Цитировать | Сообщить модератору
EAS

Цитата:
после обработки сигнала получаем заодно выход из текущей функции  

Что-то не то говоришь... Долгие (блокирующие) системные вызовы действительно прерываются с определенным кодом ошибки но текущая функция не завершается. Кажется, в некоторых ядрах, производных от SVR4 происходит перезапуск текущей функции, но сам я такого никогда не видел. Обычно, после выхода из обработчика продолжается выполнение текущей функции.
 

Цитата:
Как себе представляю (и как ~знаю), в Win, nonblock как раз на Event'ах завязаны. А вот что есть async socket в Винде тогда -- не впираю. Или я путаю?

Путаешь. nonblock и events ничего общего не имеют. Прочитай внимательно что я написал про небокирующие сокеты выше. Асинхронный сокет как раз на событиях / сигналах и построен.
 

Цитата:
Так как подобного в Win нет (аналогичной  асинхронной схемы оповещений, скажем так), то и с асинхронностью загвоздка получается

Ну приблизительно да, они в винде как-то не до конца асинхронные, т.к. ждать их так или иначе нужно.

----------
(a + b^n) / n = x, donc Dieu existe; répondez !
Euler

Всего записей: 709 | Зарегистр. 13-04-2003 | Отправлено: 15:37 02-09-2003
Открыть новую тему     Написать ответ в эту тему

Страницы: 1 2

Компьютерный форум Ru.Board » Компьютеры » Прикладное программирование » VC++: асинхронные события


Реклама на форуме Ru.Board.

Powered by Ikonboard "v2.1.7b" © 2000 Ikonboard.com
Modified by Ru.B0ard
© Ru.B0ard 2000-2024

BitCoin: 1NGG1chHtUvrtEqjeerQCKDMUi6S6CG4iC

Рейтинг.ru