Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/125.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/multithreading/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 线程未正确完成,阻止应用程序关闭_C++_Multithreading_Winapi_Exit_Winhttp - Fatal编程技术网

C++ 线程未正确完成,阻止应用程序关闭

C++ 线程未正确完成,阻止应用程序关闭,c++,multithreading,winapi,exit,winhttp,C++,Multithreading,Winapi,Exit,Winhttp,我正在编写一个win32表单应用程序,并使用Direct2D绘制它。我有几个跨线程的函数在上面做动画,我用WinHTTP做web请求。问题是,当我使用任何WinHttp函数(甚至只是打开一个HINTERNET会话)时,它将导致线程不能正确终止。在我运行一次“登录”过程后,程序无法平静地退出。我已经在下面发布了相关代码: //the login process void __cdecl processloginasync(void* arg) { //getting text from t

我正在编写一个win32表单应用程序,并使用Direct2D绘制它。我有几个跨线程的函数在上面做动画,我用WinHTTP做web请求。问题是,当我使用任何WinHttp函数(甚至只是打开一个HINTERNET会话)时,它将导致线程不能正确终止。在我运行一次“登录”过程后,程序无法平静地退出。我已经在下面发布了相关代码:

//the login process
void __cdecl processloginasync(void* arg)
{
    //getting text from textboxes, etc.

    if(usernamestr.find(L'@') != wstring::npos && usernamestr.find(L".") != wstring::npos) {
        swapdrawmode(1);
        _beginthread(loadwheel,NULL,arg);

        void* result = NULL;
        unsigned sz = 0;
        int rescode = web_request(L"appurl.mywebsite.com/func.php",ss.str().c_str(),result,sz);
        //other code to handle the reply...
        swapdrawmode(0);
    }
    else {
        error_str = L"Invalid email address.";
        err = TRUE;
    }

    if(err == TRUE) {
        textopacity = 0;
        animatemode = 0;
        _beginthread(animatetext,NULL,arg);
    }
    //I realize I haven't called 'free' on result, I'll fix that.
}

//the web_request function
int web_request (const wchar_t* server, const wchar_t* object, void*& dest, unsigned& size)
{
    vector<void*> retval;
    vector<unsigned> szs;
    HINTERNET hSess = NULL, hConn = NULL, hReq = NULL;
    int res = 0;
    DWORD dwDownloaded = 0;
    DWORD dwSize = 0;
    DWORD retcode = NULL;
    short err = FALSE;

    const wchar_t* accepted_types[] = {
        L"image/*",
        L"text/*",
        NULL
    };

    hSess = WinHttpOpen(L"smartCARS2 Web/1.1",WINHTTP_ACCESS_TYPE_DEFAULT_PROXY,WINHTTP_NO_PROXY_NAME, WINHTTP_NO_PROXY_BYPASS, 0);
    if(hSess)
        hConn = WinHttpConnect(hSess,server,INTERNET_DEFAULT_HTTP_PORT, NULL);
    else {
        err = TRUE;
        retcode = HTTP_OPEN_FAILED;
    }
    if(hConn)
        hReq = WinHttpOpenRequest(hConn, NULL, object, NULL, WINHTTP_NO_REFERER,accepted_types,NULL);
    else {
        err = TRUE;
        retcode = HTTP_CONN_FAILED;
    }
    if(hReq)
        res = WinHttpSendRequest(hReq, WINHTTP_NO_ADDITIONAL_HEADERS, NULL, WINHTTP_NO_REQUEST_DATA, NULL, NULL, NULL);
    else {
        err = TRUE;
        retcode = HTTP_OPENREQ_FAILED;
    }
    if(res)
        res = WinHttpReceiveResponse(hReq, NULL);
    else {
        err = TRUE;
        retcode = HTTP_SEND_REQ_FAILED;
    }

    DWORD tsize = 0;
    if(res) {
        do {
            dwSize = 0;
            if(!WinHttpQueryDataAvailable(hReq, &dwSize)) {
                retcode = HTTP_COULD_NOT_QUERY_SIZE;
                err = TRUE;
                break;
            }
            if(!dwSize)
                break;
            tsize += dwSize;
            void* rets = malloc(dwSize + 1);
            if(!rets) {
                break;
            }
            if(!WinHttpReadData(hReq, (void*)rets, dwSize,  &dwDownloaded)) {
                retcode = HTTP_COULD_NOT_READ_DATA;
                err = TRUE;
                break;
            }
            if(!dwDownloaded)  {
                retcode =  HTTP_COULD_NOT_DOWNLOAD;
                err = TRUE;
                break;
            }
            szs.push_back(dwSize);
            retval.push_back(rets);

        } while(dwSize > 0);
    }
    size = tsize;
    unsigned int sz = retval.size();
    dest = malloc(tsize);
    tsize = 0;
    for(unsigned i = 0; i < sz; i++) {
        memcpy((BYTE*)dest + tsize,retval[i],szs[i]);
        free(retval[i]);
        tsize += szs[i];
    }
    if(hSess)
        WinHttpCloseHandle(hSess);
    if(hConn)
        WinHttpCloseHandle(hConn);
    if(hReq)
        WinHttpCloseHandle(hReq);
    if(err == TRUE)
        return retcode;
    return 0;
}
//登录过程
void\uu cdecl processloginasync(void*arg)
{
//从文本框等获取文本。
if(usernamestr.find(L'@')!=wstring::npos&&usernamestr.find(L“)!=wstring::npos){
swapdraw模式(1);
_beginthread(loadwheel,NULL,arg);
void*result=NULL;
无符号sz=0;
int rescode=web_请求(L“appurl.mywebsite.com/func.php”,ss.str().c_str(),result,sz);
//处理回复的其他代码。。。
swapdrawmode(0);
}
否则{
错误\u str=L“无效的电子邮件地址。”;
错误=正确;
}
if(err==TRUE){
textopacity=0;
animatemode=0;
_beginthread(animatetext,NULL,arg);
}
//我意识到我并没有对结果调用“free”,我会解决这个问题。
}
//web_请求函数
int web_请求(常量wchar_t*服务器、常量wchar_t*对象、void*&dest、unsigned&size)
{
向量检索;
矢量sz;
HINTERNET hSess=NULL,hConn=NULL,hReq=NULL;
int res=0;
DWORD=0;
DWORD dwSize=0;
DWORD retcode=NULL;
短错误=错误;
常量wchar_t*接受的类型[]={
L“image/*”,
L“text/*”,
无效的
};
hSess=WinHttpOpen(L“smartCARS2 Web/1.1”,WINHTTP\u访问类型\u默认代理,WINHTTP\u无代理\u名称,WINHTTP\u无代理\u旁路,0);
如果(hSess)
hConn=WinHttpConnect(hSess、服务器、INTERNET\u默认\u HTTP\u端口,空);
否则{
错误=正确;
retcode=HTTP\u OPEN\u失败;
}
如果(hConn)
hReq=WinHttpOpenRequest(hConn,NULL,object,NULL,WINHTTP\u NO\u REFERER,accepted\u type,NULL);
否则{
错误=正确;
retcode=HTTP\u CONN\u失败;
}
如果(hReq)
res=WinHttpSendRequest(hReq,WINHTTP\u NO\u附加\u头,NULL,WINHTTP\u NO\u请求\u数据,NULL,NULL,NULL);
否则{
错误=正确;
retcode=HTTP_OPENREQ_失败;
}
如果(res)
res=WinHttpReceiveResponse(hReq,NULL);
否则{
错误=正确;
retcode=HTTP_发送_请求_失败;
}
DWORD tsize=0;
如果(res){
做{
dwSize=0;
如果(!WinHttpQueryDataAvailable(hReq和dwSize)){
retcode=HTTP\u无法\u查询\u大小;
错误=正确;
打破
}
如果(!dwSize)
打破
tsize+=dwSize;
void*rets=malloc(dwSize+1);
如果(!rets){
打破
}
if(!WinHttpReadData(hReq,(void*)rets、dwSize和dwDownloaded)){
retcode=HTTP\u无法\u读取\u数据;
错误=正确;
打破
}
如果(!dw下载){
retcode=HTTP\u无法下载;
错误=正确;
打破
}
szs.推回(dwSize);
返回。推回(rets);
}而(dwSize>0);
}
尺寸=t尺寸;
unsigned int sz=retval.size();
dest=malloc(tsize);
tsize=0;
for(无符号i=0;i
据我所知,只要主线程终止,其他线程就不会等待。所以问题可能出在你的主线上。如果尚未调试,只需将调试器(Debug | attach to process in VS)附加到僵尸进程,然后按“全部中断”,然后使用“线程”和“调用堆栈”窗口了解发生的情况。

执行代码有点困难。你能定义一下冷静终止的意思吗?我为此道歉,我发了很多帖子,因为我只是部分确定问题所在。我的意思是,如果你关闭程序(点击X),尽管线程似乎已经结束(它们没有在它们的进程中触发断点),进程继续运行。你也可以考虑<代码>动画版> <代码>和<代码>加载轮< /代码>是否也被正确关闭。这些线程似乎都没有等待适当的完成。在代码中的适当位置,可以考虑使用获得一个有效的可等待句柄和<代码> WaFutSunLeObjutt()/<代码>或<代码> WaistFrimeType Objs/Cuth>。找出阻止主线程退出的原因-具有接收WM_CLOSE消息的主窗口的线程。WndProc接收WM_CLOSE并发布退出消息。“main”函数也返回0,尽管僵尸进程仍在继续。这是有道理的,但是,我测试时根本没有创建任何线程,问题仍然存在,只是由于调用了任何WinHTTP函数。Break All确实显示了几个线程,但没有一个线程是直接由用户创建的。我发现调用“exit(0);”在main的末尾,它终止了,但我怀疑这是否是一个好的做法。从你所说的,我认为你在一个全局析构函数中遇到了问题。请在僵尸进程中复制主线程的堆栈(例如,您可以通过ID找到它,在开始时记住它)。主线程返回0并结束,后续动画线程也是如此。没有用户创建的运行,它们都类似于'_NtWaitForWorkViaWorkerFactory@16'并且只存在一次WinHTTP