Следующий фрагмент кода C ++ использует Microsoft C ++ Rest SDK. Я не понимаю, почему первый фрагмент работает, а другой нет. Я предполагаю, что различия связаны с разрушением объекта и правилами определения области видимости. Я ищу объяснение того, почему первый фрагмент работает, а другие фрагменты зависают при закрытии (). Кроме того, что может сделать SDK для устранения ошибок в будущем. Некоторые действительно умные люди смотрели на фрагмент, но никогда не видели проблему.
Первый фрагмент кода. Этот фрагмент работает и показан в полном объеме. Последующие фрагменты кода заменяют помеченный код внутри. Пожалуйста, сосредоточьтесь на различиях, а не на других отвлекающих моментах. Код был протестирован путем выполнения одного запроса GET в браузере и пошагового выполнения кода. Во всех случаях request.reply () выполнялся один раз и только один раз.
boost::lockfree::spsc_queue<web::http::http_request, boost::lockfree::capacity<1024>> queue;
web::http::experimental::listener::http_listener listener(U("http://localhost:3901"));
listener.support([&](web::http::http_request request)
{
queue.push(request);
});
listener.open().wait();
std::cout << "listening ... hit enter to initiate shutdown." << std::endl;
std::getchar();
// BEGIN CODE IN QUESTION
while (!queue.empty())
{
web::http::http_request request;
if (queue.pop(request))
request.reply(web::http::status_codes::ServiceUnavailable, U("Service Unavailable")).wait();
}
// END CODE IN QUESTION
listener.close().wait();
Второй фрагмент кода. Зависает от закрытия ().
// hangs on close().wait()
web::http::http_request request;
while (queue.try_pop(request))
{
request.reply(web::http::status_codes::ServiceUnavailable, U("Service Unavailable")).wait();
}
Третий фрагмент кода. Зависает от закрытия ().
// hangs on close().wait(). Outer braces make no difference.
{
web::http::http_request request;
while (queue.try_pop(request))
{
request.reply(web::http::status_codes::ServiceUnavailable, U("Service Unavailable")).wait();
request.~http_request();
}
}
Четвёртый фрагмент кода. Зависает от закрытия (). Внешние брекеты не имеют значения.
// hangs on close().wait()
{
web::http::http_request request;
while (queue.try_pop(request))
{
request.reply(web::http::status_codes::ServiceUnavailable, U("Service Unavailable")).wait();
request.~http_request();
}
request.~http_request();
}
Обновление: поддерживая объяснение Мэтта Макнабба, следующий код работает, если я только выпускаю один GET. Я просто удалил цикл для обработки одного GET. Явный вызов деструктора требуется, чтобы избежать зависания, но это неправильная практика.
web::http::http_request request;
requests.pop(request);
request.reply(web::http::status_codes::ServiceUnavailable, U("Service Unavailable")).wait();
request.~http_request();
Обновление: явный вызов деструктора после цикла заставляет программу работать для одного GET. Однако два или более GET выдают исключение. Я не уверен почему.
web::http::http_request request;
while (queue.try_pop(request))
{
request.reply(web::http::status_codes::ServiceUnavailable, U("Service Unavailable")).wait();
}
request.~http_request();
Отказ от ответственности: без каких-либо знаний об этой библиотеке, это довольно опасно
#include <iostream>
using namespace std;
class Obj {
public:
Obj() {
cout << "Constructor" << endl;
}
~Obj() {
cout << "Destructor" << endl;
}
};
int main() {
{
Obj ea;
ea.~Obj();
}
return 0;
}
Выход:
Constructor
Destructor
Destructor
Если есть ресурсы, которые нужно освободить, или операции, которые нужно выполнить для очистки запроса, вы создаете много проблем в каждом случае, кроме случаев, когда вы выполняете следующие шаги:
pop
или же try_pop
)В фрагментах выше:
Проблема с каждым из этих примеров, кажется, та же самая: несоответствующая конструкция и уничтожение объекта запроса. Я редко видел такую изобретательность в том, чтобы делать это неправильно.
Простое решение:
Казалось бы, его нужно уничтожить перед вызовом close (), что разумно.
Под этим я подразумеваю, что второй пример — единственный, в котором объект вообще не разрушен, и он тоже терпит неудачу. Я предполагаю, что это по какой-то другой причине не видно в этом коде.