#c #multithreading #wininet
#c #многопоточность #вининет
Вопрос:
Я хотел бы получить второе мнение о моем использовании потоков std::, чтобы проверить, не зависает ли HttpSendRequestA слишком долго.(если сервер находится в режиме ожидания). Флаг тайм-аута ничего не делает в запросах WinInet.
Мое решение состоит в том, чтобы создавать новый поток для каждого запроса, устанавливая 3-секундную проверку. Когда HttpSendRequestA завершена — значение в потоке равно 1, указывая ему на выход, ничего не делая. Если поток завершается до завершения HttpSendRequestA — это означает, что на сервере истек тайм — аут, — поток освобождает дескриптор hData, позволяя приложению продолжить;
Воспроизводимый пример здесь:
class MyThread { public: std::atomiclt;intgt; iDone = 0; HINTERNET hData; void Add() { Sleep(3000); int iDoneTemp = iDone; if (iDoneTemp == 0) { InternetCloseHandle(hData); } } }; #include lt;windows.hgt; #include lt;wininet.hgt; #include lt;stringgt; #include lt;stdio.hgt; #include lt;stdlib.hgt; using namespace std; #pragma comment ( lib, "Wininet.lib" ) HINTERNET hInternet = InternetOpenA("InetURL/1.0", INTERNET_OPEN_TYPE_PRECONFIG, NULL, NULL, 0); DWORD dwTimeout = 300; InternetSetOption(hInternet, INTERNET_OPTION_RECEIVE_TIMEOUT, amp;dwTimeout, sizeof(DWORD)); HINTERNET hConnection = InternetConnectA(hInternet, "httpstat.us", 80, " ", " ", INTERNET_SERVICE_HTTP, 0, 0); InternetSetOption(hConnection, INTERNET_OPTION_RECEIVE_TIMEOUT, amp; dwTimeout, sizeof(DWORD)); HINTERNET hData = HttpOpenRequestA(hConnection, "GET", "/200?sleep=5000", NULL, NULL, NULL, INTERNET_FLAG_KEEP_CONNECTION, 0); InternetSetOption(hData, INTERNET_OPTION_RECEIVE_TIMEOUT, amp; dwTimeout, sizeof(DWORD)); MyThread* MyNewThread = new MyThread; thread NewThread(amp;MyThread::Add, std::ref((*MyNewThread))); MyNewThread-gt;hData = hData; NewThread.detach(); HttpSendRequestA(hData, NULL, 0, NULL, 0); MyNewThread-gt;iDone = 1;
Комментарии:
1. Я думаю, что это нормально. Win32 API очень надежен, когда дело доходит до проблем с потоковой передачей. На самом деле, я использую аналогичный трюк с WinSock, и он отлично работает.