Модераторы: Daevaorn
  

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> Ctrl-C и Windows 
:(
    Опции темы
drug007
Дата 16.12.2012, 15:01 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Бывалый
*


Профиль
Группа: Участник
Сообщений: 196
Регистрация: 3.11.2011

Репутация: нет
Всего: 1



Не совсем подходящее место, возможно. Но подскажите, кто может - в линуксе, нажав Ctrl-C, я посылаю сигнал процессу и все системные вызовы прерываются со значением -1 и ошибкой errno == EINTR. В винде же, когда я устанавливаю обработчик Ctrl-C с помощью SetConsoleCtrlHandler, обработчик-то вызывается, как положено, но вот системные вызовы не прерываются. И если приложение ждет данных по сети, то оно зависает даже несмотря на Ctrl-C. И только прочитав данные из сети приложение выходит. Как можно обойти это ограничение? Понятно, что я могу переписать приложение, чтобы оно мониторило данные на дескрипторе и читало только когда данные пришли, но хотелось бы более портабельный код.
PM MAIL   Вверх
feodorv
Дата 16.12.2012, 15:20 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Комодератор
Сообщений: 2214
Регистрация: 30.7.2011

Репутация: 11
Всего: 45



Цитата(drug007 @  16.12.2012,  16:01 Найти цитируемый пост)
Как можно обойти это ограничение?

Боюсь, портабельным образом - никак. Хотя, может быть, boost поможет...
Впрочем, сигналы для Windows - это тоже чужеродное явление, никак не портабельное.


Это сообщение отредактировал(а) feodorv - 16.12.2012, 15:21


--------------------
Напильник, велосипед, грабли и костыли - основные инструменты программиста...
PM MAIL   Вверх
drug007
Дата 16.12.2012, 16:42 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Бывалый
*


Профиль
Группа: Участник
Сообщений: 196
Регистрация: 3.11.2011

Репутация: нет
Всего: 1



А как можно прервать в Windows системный вызов? Чтобы попробовать сымитировать такое поведение.
PM MAIL   Вверх
feodorv
Дата 18.12.2012, 11:37 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Комодератор
Сообщений: 2214
Регистрация: 30.7.2011

Репутация: 11
Всего: 45



Цитата(drug007 @  16.12.2012,  17:42 Найти цитируемый пост)
А как можно прервать в Windows системный вызов? Чтобы попробовать сымитировать такое поведение. 

Обычно создают специальное событие, которое добавляют в список объектов для Wait-функций, и для которого делают SetEvent в обработчике ^C. Для этого всё работу по сети придётся переводить на неблокирующие или асинхронные сокеты...
Можно пробовать просто закрыть сокет, системный вызов должен вывалиться с соответствующей ошибкой, но это очень грубо.


--------------------
Напильник, велосипед, грабли и костыли - основные инструменты программиста...
PM MAIL   Вверх
xvr
Дата 18.12.2012, 12:29 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Комодератор
Сообщений: 7046
Регистрация: 28.8.2007
Где: Дублин, Ирландия

Репутация: 60
Всего: 223



Цитата(feodorv @  18.12.2012,  11:37 Найти цитируемый пост)
Для этого всё работу по сети придётся переводить на неблокирующие или асинхронные сокеты...

Необязательно. Вот есть статья ...

PM MAIL   Вверх
borisbn
Дата 18.12.2012, 12:31 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Завсегдатай
Сообщений: 4875
Регистрация: 6.2.2010
Где: Ростов-на-Дону

Репутация: 22
Всего: 135



Цитата(feodorv @  18.12.2012,  11:37 Найти цитируемый пост)
Можно пробовать просто закрыть сокет, системный вызов должен вывалиться с соответствующей ошибкой, но это очень грубо. 

хммм.. всегда так делал... думал, что это - обычный способ: закрыть все открытые handle'ы, функции ожидания этих хэндлов прервутся, и мне останется только дождаться завершения запущенных потоков (join). А что тут "грубого" ?

вопрос к drug007, а как Вы штатно завершаете приложение ?

Добавлено через 11 минут и 14 секунд
xvr, интересная статья, но... решение для асинхронных операций выглядит ужасно
Цитата
The application needs to maintain a list of handles to devices to which I/O operations are executed. Whenever the application opens a device for asynchronous I/O operation (say, using CreateFile, OpenFile, etc), it must update the global list of device handles (and remove the handle while closing the device using CloseHandle API).
 
для синхронных же - вполне норм.


--------------------
Женщины отличаются от программистов тем, что у них чары состоят из стрингов
PM MAIL Jabber   Вверх
feodorv
Дата 18.12.2012, 14:40 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Комодератор
Сообщений: 2214
Регистрация: 30.7.2011

Репутация: 11
Всего: 45



Цитата(borisbn @  18.12.2012,  13:31 Найти цитируемый пост)
А что тут "грубого" ?

Грубо по отношению к потоку, который использует этот сокет. Этот поток должен быть готов к внезапной кончине сокета, виси он на синхронной функции или занимайся другими делами. Если этим пользоваться только при закрытии программы, то, может, и нормальный способ. В общем случае можно получить неприятности (скажем, другой поток в этот момент открывает сокет, хендлер которого по случайности оказывается равным ранее закрытому хендлеру сокета). Да и с shutdown как быть непонятно...


--------------------
Напильник, велосипед, грабли и костыли - основные инструменты программиста...
PM MAIL   Вверх
drug007
Дата 20.12.2012, 08:35 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Бывалый
*


Профиль
Группа: Участник
Сообщений: 196
Регистрация: 3.11.2011

Репутация: нет
Всего: 1



Извиняюсь, что долго не заходил
Цитата(borisbn @ 18.12.2012,  12:31)

хммм.. всегда так делал... думал, что это - обычный способ: закрыть все открытые handle'ы, функции ожидания этих хэндлов прервутся, и мне останется только дождаться завершения запущенных потоков (join). А что тут "грубого" ?

вопрос к drug007, а как Вы штатно завершаете приложение ?

Дело в том, что я сейчас знакомлюсь с библиотекой zeromq и портирую некоторые примеры из руководства на язык D. Как в библиотеке реализовано завершение работы, честно говоря, не смотрел. Под никсами при вызове библиотечной функции zmq::ctx _t::terminate() все синхронные вызовы возвращают -1 и устанавливают ошибку EINTR. Под виндой же синхронные вызовы ждут, чтобы хоть что пришло и только после этого возвращают управление. В принципе, более сложные примеры, использующие поллинг дескриптора перед работой с ним, правильно работают и под виндой. А вот простые примеры в винде не работают - без поллинга чтение из сокета подвешивает приложение пока что-то не придет на этот сокет и только потом приложение завершается, что новичка (а туториал же для них) будет сбивать с толку.  Делать поллинг в простых примерах тоже не комильфо - я же не автор руководства, а лишь портирую его на другой язык. Вот и хотел посоветоваться, как можно простым способом решить этот вопрос. Пока в качестве workaround'а вижу только прямой текст, что так и так, под windows вы получите такой и такой эффект по такой-то и такой-то причине...

xvr, спасибо за статью, но слишком сложное решение в данном случае.

Добавлено @ 08:39
Цитата(feodorv @ 18.12.2012,  14:40)

Грубо по отношению к потоку, который использует этот сокет. Этот поток должен быть готов к внезапной кончине сокета, виси он на синхронной функции или занимайся другими делами. Если этим пользоваться только при закрытии программы, то, может, и нормальный способ. В общем случае можно получить неприятности (скажем, другой поток в этот момент открывает сокет, хендлер которого по случайности оказывается равным ранее закрытому хендлеру сокета). Да и с shutdown как быть непонятно...

shutdown обычно редко кто пользует (хотя, конечно, стоило бы учитывать его наличие). что же насчет готовности потока - по идее в любом случае он должен быть готов к тому, что события на дескрипторе будут развиваться как угодно. мы же ошибки должны обрабатывать?

Это сообщение отредактировал(а) drug007 - 20.12.2012, 08:43
PM MAIL   Вверх
  
Ответ в темуСоздание новой темы Создание опроса
Правила форума "С++:Общие вопросы"
Earnest Daevaorn

Добро пожаловать!

  • Черновик стандарта C++ (за октябрь 2005) можно скачать с этого сайта. Прямая ссылка на файл черновика(4.4мб).
  • Черновик стандарта C (за сентябрь 2005) можно скачать с этого сайта. Прямая ссылка на файл черновика (3.4мб).
  • Прежде чем задать вопрос, прочтите это и/или это!
  • Здесь хранится весь мировой запас ссылок на документы, связанные с C++ :)
  • Не брезгуйте пользоваться тегами [code=cpp][/code].
  • Пожалуйста, не просите написать за вас программы в этом разделе - для этого существует "Центр Помощи".
  • C++ FAQ

Если Вам понравилась атмосфера форума, заходите к нам чаще! С уважением, Earnest Daevaorn

 
0 Пользователей читают эту тему (0 Гостей и 0 Скрытых Пользователей)
0 Пользователей:
« Предыдущая тема | C/C++: Общие вопросы | Следующая тема »


 




[ Время генерации скрипта: 0.0531 ]   [ Использовано запросов: 22 ]   [ GZIP включён ]


Реклама на сайте     Информационное спонсорство

 
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности     Powered by Invision Power Board(R) 1.3 © 2003  IPS, Inc.