Здравствуйте, xentry, Вы писали:
X>Здравствуйте, Armastab, Вы писали:
A>>Иногда (при указанной нагрузке 20 клиентов, в среднем раз в 30 секунд, иногда чаще, иногда реже), WSASend и WSARecv вываливаются с исключением 0x00000005 Access violation.
A>>При этом поля класса pIOReq оказываются невалидными, как будто объект удален. Данное исключение выскакивает в отладчике и не перехватывается ни try-catch ни __try — __except
X>Вероятно в этот момент удалена структура CIOReq или сами буфера чтения/записи. Поскольку сама асинхронная операция в этот момент выполняется не в рабочем потоке процесса система выплевывает исключение которое не будет поймано. Или будет поймано "без стека", или вы увидите на экране "Приложение выполнило недопустимую операцию и будет закрыто", если отладки не было.
О, спасибо. Мне в голову как-то даже не пришло, что операция не в рабочем потоке выполняется.
A>>Экспериментально выяснилось, если количество рабочих потоков сделать равным 1 (обычно запущено 10), такой ошибки не возникает.
A>>Если сделать защиту (собственный механизм) указателя pIOReq от удаления, до возврата из WSASend, WSARecv, то ошибки тоже не возникает, а отлавливается попытка удалить объект до снятия защиты.
X>Это потому что в одном потоке все вызовы будут сериализированы.
Ага, до это я догадался.
A>>Из всего вышеописанного у меня сложилось ощущение, что один из ожидающих рабочих потоков получает управление и сигнал о завершении ввода-вывода, еще до того как произошел возврат из WSASend WSARecv.
A>>Он удаляет объект pIOReq и в WSASend/WSARecv происходит нарушение доступа.
X>Тут сложно сказать наверняка, не видя кода, но это предположение скорее всего ошибочное.
В данный момент удаление структуры (по крайней мере оператор delete) CIOReq происходит в единственном месте — рабочем потоке, после того как он получает сигнал о завершении операции ввода/вывода, именно в этом месте наблюдается переодическая попытка удаления структуры, защищенной от удаления, хотя, конечно, это теоретически может происходить и в промежуток между командой WSARecv и следующим за ней снятием защиты.
X>Отлаживать
Стоит подумать о счетчике ссылок в CIOReq (раз уж есть механизм защиты от его удаления)
Ну, собственно, механизм защиты и реализован через примитивный счетчик ссылок, правда не в самом CIOReq а во внешнем объекте. Это, конечно, избавляет от исключений, но что-то мне подсказывает, что такой ошибки быть не должно. Спасибо за информацию, буду отлаживать.