首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >C++映射迭代和堆栈损坏

C++映射迭代和堆栈损坏
EN

Stack Overflow用户
提问于 2012-05-27 10:03:45
回答 1查看 456关注 0票数 2

我正在尝试使用地图系统来存储和更新聊天服务器的数据。应用程序是多线程的,并使用锁系统来防止多线程访问数据。

问题是:当一个客户端从映射中单独删除时,它是可以的。然而,当我尝试调用多个close时,它会在内存中留下一些。如果我在任何时候调用map上的::clear(),它会导致调试断言错误,或者是"Iterator不兼容“或类似的错误。代码将在第一次运行(使用作为测试连接的80+控制台进行测试),但由于它会留下块,因此不会再次运行。我已经尝试过研究方法,并且我已经编写了系统来停止代码执行,直到每个进程完成。我非常感谢到目前为止的任何帮助,我已经附上了相关的代码片段。

代码语言:javascript
运行
复制
//portion of server code that handles shutting down
DWORD WINAPI runserver(void *params) {  
    runserverPARAMS *p = (runserverPARAMS*)params;  
    /*Server stuff*/                            

    serverquit = 0; 
    //client based cleanup
    vector<int> tokill;
    map<int,int>::iterator it = clientsockets.begin();

    while(it != clientsockets.end()) {      
        tokill.push_back(it->first);
        ++it;
    }
    for(;;) {
        for each (int x in tokill) {
            clientquit[x] = 1;
            while(clientoffline[x] != 1) {
                //haulting execution until thread has terminated
            }
            destoryclient(x);
        }
    }
    //client thread based cleanup complete.
    return 0;
}


//clientioprelim
DWORD WINAPI clientioprelim(void* params) {
    CLIENTthreadparams *inparams = (CLIENTthreadparams *)params;
    /*Socket stuff*/
    for(;;) {       
        /**/
        }
        else {
            if(clientquit[inparams->clientid] == 1)
                break;
        }
    }
    clientoffline[inparams->clientid] = 1;
    return 0;
}

int LOCKED; //exported as extern via libraries.h so it's visible to other source files

void destoryclient(int clientid) {
    for(;;) {
        if(LOCKED == 0) {
            LOCKED = 1;         
            shutdown(clientsockets[clientid], 2);
            closesocket(clientsockets[clientid]);
            if((clientsockets.count(clientid) != 0) && (clientsockets.find(clientid) != clientsockets.end()))
                clientsockets.erase(clientsockets.find(clientid));                  
            if((clientname.count(clientid) != 0) && (clientname.find(clientid) != clientname.end()))
                clientname.erase(clientname.find(clientid));
            if((clientusername.count(clientid) != 0) && (clientusername.find(clientid) != clientusername.end()))
                clientusername.erase(clientusername.find(clientid));
            if((clientaddr.count(clientid) != 0) && (clientaddr.find(clientid) != clientaddr.end()))
                clientaddr.erase(clientusername.find(clientid));
            if((clientcontacts.count(clientid) != 0) && (clientcontacts.find(clientid) != clientcontacts.end())) 
                clientcontacts.erase(clientcontacts.find(clientid));
            if((clientquit.count(clientid) != 0) && (clientquit.find(clientid) != clientquit.end()))
                clientquit.erase(clientquit.find(clientid));    
            if((clientthreads.count(clientid) != 0) && (clientthreads.find(clientid) != clientthreads.end())) 
                clientthreads.erase(clientthreads.find(clientid));
            LOCKED = 0;
            break;          
        }
    }
    return;
}
EN

Stack Overflow用户

回答已采纳

发布于 2012-05-27 10:28:59

您是否真的在使用int进行锁定,或者只是简化了代码?如果你真的使用了一个int:这是行不通的,如果两个线程都在一个线程赋值之前检查变量,那么临界区可以同时输入两次(或更多)(简化)。有关参考,请参阅mutexes in Wikipedia。您可以使用intboost thread提供的某种互斥锁来代替windows。

票数 0
EN
查看全部 1 条回答
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/10771152

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档