在一個(gè)界面中的按鈕事件中需要向 所有在線的服務(wù)器 發(fā)送信息
void Dialog::Button_Click()
{
????map <unsigned long, CServer*>::iterator iter;
??? for ( iter = m_OnLineServers.begin(); iter != m_OnLineServers.end(); iter++ )
??? {
???????? iter->second->sendMsg();
??? }
}
所有 在線服務(wù)器 都存放在? m_OnLineServers? 這個(gè)列表中,這個(gè)列表是一個(gè) std::map
sendMsg()?? 內(nèi)部又調(diào)用了 SOCKET 函數(shù)的 send
當(dāng) send 執(zhí)行失敗時(shí),? 會(huì)通知 Dialog 的? OnServerClose() 事件
void Dialog::OnServerClose(int nIndex)
{
??map <unsigned long, CServer*>::iterator iter???= m_OffLineServers.find(nIndex);
??if ( iter != m_OffLineServers.end() )
??{
???m_OffLineServers.insert(make_pair<unsigned long, CServer*>(nIndex, iter_find->second));
???m_OnLineServers.erase(nIndex);
??}
OnServerClose() 事件需要把 CServer 從 Online 列表中刪除, 跟著添加到 OffLine 列表
結(jié)合起來(lái)看,就會(huì)出現(xiàn)在同一條線程中
遍歷 map
{
??? 刪除 map 元素
}
google了一下,網(wǎng)友們?cè)诒闅v的過(guò)程中刪除元素的方法是
for(iter = list.begin(); iter != list.end();)
{
??? if (shouldDelete(*iter))
?????? iter = list.erase(iter);
??? else
?????? ++iter;
}
似乎能解決問(wèn)題,
但從上面的邏輯來(lái)看, 遍歷跟刪除, 分別是在兩個(gè)不同的類, 這樣一來(lái)邏輯就復(fù)雜多了
通常BUG都是因?yàn)閺?fù)雜的邏輯而產(chǎn)生的。
Feedback
# re: 復(fù)雜的邏輯的BUG 回復(fù) 更多評(píng)論
2009-03-04 09:07 by LOGOS遍歷的過(guò)程很可能會(huì)調(diào)用一些刪除操作,而且調(diào)用得很隱含
這樣的情況是有的,而且不算什么異常的事情
這種情況下采用異步的刪除機(jī)制就可以了
這樣的情況是有的,而且不算什么異常的事情
這種情況下采用異步的刪除機(jī)制就可以了
# re: 復(fù)雜的邏輯的BUG 回復(fù) 更多評(píng)論
2009-03-04 09:19 by qtopia發(fā)送消息的時(shí)候,建立一份m_onlineServers的拷貝,在拷貝中發(fā)送消息
# re: 復(fù)雜的邏輯的BUG 回復(fù) 更多評(píng)論
2009-03-04 09:37 by zuhd只要是同一份內(nèi)存數(shù)據(jù),在同一個(gè)線程中,就不會(huì)出現(xiàn)所謂沖突的問(wèn)題,仔細(xì)檢查下代碼,看看,你后面說(shuō)的遍歷刪除map的問(wèn)題是防止刪除最后一個(gè)元素的時(shí)候越界
# re: 復(fù)雜的邏輯的BUG 回復(fù) 更多評(píng)論
2009-03-04 15:13 by Nobody迭代器遍歷的時(shí)候,如果對(duì)容器添加或者刪除元素,容易造成混亂。
| 只有注冊(cè)用戶登錄后才能發(fā)表評(píng)論。 | ||
|
||
|
相關(guān)文章:
|
||
網(wǎng)站導(dǎo)航:
博客園
IT新聞
BlogJava
博問(wèn)
Chat2DB
管理
|
||
|
|


