首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> 更多程式語言 >> 程式設計綜合問答

MFC 多線程 FTP 連接:參數生命週期導致異常的定位與修復

     編輯:程式設計綜合問答

錯誤現象

AfxBeginThread(mtQuery, pParam, ...) 調用後,線程函數 mtQuery 內訪問 pParam 成員時崩潰/報錯。

根本原因

主線程在啟動工作線程後,過早釋放/刪除了參數結構體內存。

// 主線程錯誤示例
PPARAM pParam = new PARAM;  // 分配
pParam->pListBox = ...;
AfxBeginThread(mtQuery, pParam); // 異步啟動
delete pParam; // 錯誤!工作線程可能尚未讀取參數

正確做法

  1. 參數由工作線程負責釋放:在 mtQuery 結束前 delete pParam。
  2. 或使用智能指針/共享所有權(C++11 std::shared_ptr)。
  3. 或參數分配在堆上且生命週期 ≥ 線程結束(如成員變量)。

修正後線程函數

UINT _cdecl mtQuery(LPVOID pParam) {
    PPARAM pparam = (PPARAM)pParam;
    // ... 使用 pparam 成員 ...
    
    // 線程結束前釋放參數內存
    delete pparam; 
    return 0;
}

完整安全模式 (C++11)

// 主線程
auto params = std::make_shared();
params->pListBox = m_listBox;
params->strFtp = _T("ftp://...");
AfxBeginThread([](LPVOID p) {
    auto p = static_cast*>(p);
    // 使用 (*p)->member
    // 共享指針離開作用域自動釋放
}, new std::shared_ptr(params)); // 傳遞 shared_ptr 指針

其他注意點

  • UI 控件 (CListBox*) 跨線程訪問需 PostMessage 或鎖,不能直接在工作線程調用 AddString(MFC UI 非線程安全)。
  • FTP 連接對象 (CInternetSession, CFtpConnection) 必須在線程內創建、使用、銷毀,不可跨線程共享。
  • 異常處理:捕獲 CInternetException 並通過 PostMessage 通知主線程顯示錯誤。

總結

多線程參數傳遞核心原則:**誰創建誰釋放,或明確所有權轉移**。主線程啟動線程後不可立即銷毀參數,需由工作線程在使用完畢後釋放。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved