网站免费云主机,跨境电商平台设计,专门做特产的网站,wordpress get field添加线程安全结束代码的原因#xff1a;1.如果对话框关闭时线程仍在运行#xff0c;访问已释放内存程序崩溃#xff01;2. 资源泄漏风险如线程句柄未关闭、内存未释放、 GDI对象未释放、文件句柄未关闭#xff0c;程序看似关闭#xff0c;但进程仍在后台运行#xff0c;再…添加线程安全结束代码的原因1.如果对话框关闭时线程仍在运行访问已释放内存程序崩溃2. 资源泄漏风险如线程句柄未关闭、内存未释放、 GDI对象未释放、文件句柄未关闭程序看似关闭但进程仍在后台运行再次启动程序可能失败。这里增加一个SafeTerminateThread()函数用于线程安全结束在对话框析构函数、OnDestroy消息处理、及停止按钮中调用于线程安全函数。改进后完整代码如下。SimpleThreadDemoDlg.h// SimpleThreadDemoDlg.h : header file//#if!defined(AFX_SIMPLETHREADDEMODLG_H__1FDB3406_48D0_44E7_9CE2_1977BCCA5492__INCLUDED_)#defineAFX_SIMPLETHREADDEMODLG_H__1FDB3406_48D0_44E7_9CE2_1977BCCA5492__INCLUDED_#if_MSC_VER1000#pragmaonce#endif// _MSC_VER 1000/////////////////////////////////////////////////////////////////////////////// CSimpleThreadDemoDlg dialogclassCSimpleThreadDemoDlg:publicCDialog{// Constructionpublic:CSimpleThreadDemoDlg(CWnd*pParentNULL);// standard constructorvirtual~CSimpleThreadDemoDlg();// 析构函数// 线程句柄HANDLE m_hThread;// 事件对象用于线程同步HANDLE m_hStopEvent;// 线程控制标志// 线程控制BOOL m_bStopThread;// TRUE表示线程应该停止BOOL m_bThreadActive;// TRUE表示线程正在运行// 线程参数结构structTHREAD_PARAM{CSimpleThreadDemoDlg*pDlg;intnCounter;};private:// 添加安全终止方法voidSafeTerminateThread();// 静态线程函数staticUINTThreadProc(LPVOID pParam);// 线程工作函数voidDoThreadWork(intnIteration);// Dialog Data//{{AFX_DATA(CSimpleThreadDemoDlg)enum{IDDIDD_SIMPLETHREADDEMO_DIALOG};// NOTE: the ClassWizard will add data members here//}}AFX_DATA// ClassWizard generated virtual function overrides//{{AFX_VIRTUAL(CSimpleThreadDemoDlg)protected:virtualvoidDoDataExchange(CDataExchange*pDX);// DDX/DDV support//}}AFX_VIRTUAL// Implementationprotected:HICON m_hIcon;// Generated message map functions//{{AFX_MSG(CSimpleThreadDemoDlg)virtualBOOLOnInitDialog();afx_msgvoidOnSysCommand(UINT nID,LPARAM lParam);afx_msgvoidOnPaint();afx_msg HCURSOROnQueryDragIcon();afx_msgvoidOnButtonStart();afx_msgvoidOnButtonStop();afx_msgvoidOnDestroy();//}}AFX_MSGDECLARE_MESSAGE_MAP()};//{{AFX_INSERT_LOCATION}}// Microsoft Visual C will insert additional declarations immediately before the previous line.#endif// !defined(AFX_SIMPLETHREADDEMODLG_H__1FDB3406_48D0_44E7_9CE2_1977BCCA5492__INCLUDED_)SimpleThreadDemoDlg.cpp// SimpleThreadDemoDlg.cpp : implementation file//#includestdafx.h#includeSimpleThreadDemo.h#includeSimpleThreadDemoDlg.h#ifdef_DEBUG#definenewDEBUG_NEW#undefTHIS_FILEstaticcharTHIS_FILE[]__FILE__;#endif// 线程参数结构体/////////////////////////////////////////////////////////////////////////////// CAboutDlg dialog used for App AboutclassCAboutDlg:publicCDialog{public:CAboutDlg();// Dialog Data//{{AFX_DATA(CAboutDlg)enum{IDDIDD_ABOUTBOX};//}}AFX_DATA// ClassWizard generated virtual function overrides//{{AFX_VIRTUAL(CAboutDlg)protected:virtualvoidDoDataExchange(CDataExchange*pDX);// DDX/DDV support//}}AFX_VIRTUAL// Implementationprotected://{{AFX_MSG(CAboutDlg)//}}AFX_MSGDECLARE_MESSAGE_MAP()};CAboutDlg::CAboutDlg():CDialog(CAboutDlg::IDD){//{{AFX_DATA_INIT(CAboutDlg)//}}AFX_DATA_INIT}voidCAboutDlg::DoDataExchange(CDataExchange*pDX){CDialog::DoDataExchange(pDX);//{{AFX_DATA_MAP(CAboutDlg)//}}AFX_DATA_MAP}BEGIN_MESSAGE_MAP(CAboutDlg,CDialog)//{{AFX_MSG_MAP(CAboutDlg)// No message handlers//}}AFX_MSG_MAPEND_MESSAGE_MAP()/////////////////////////////////////////////////////////////////////////////// CSimpleThreadDemoDlg dialogCSimpleThreadDemoDlg::CSimpleThreadDemoDlg(CWnd*pParent/*NULL*/):CDialog(CSimpleThreadDemoDlg::IDD,pParent){//{{AFX_DATA_INIT(CSimpleThreadDemoDlg)m_bStopThreadFALSE;// 不要停止m_bThreadActiveFALSE;// 线程不在运行m_hThreadNULL;//}}AFX_DATA_INIT// Note that LoadIcon does not require a subsequent DestroyIcon in Win32m_hIconAfxGetApp()-LoadIcon(IDR_MAINFRAME);}voidCSimpleThreadDemoDlg::DoDataExchange(CDataExchange*pDX){CDialog::DoDataExchange(pDX);//{{AFX_DATA_MAP(CSimpleThreadDemoDlg)// NOTE: the ClassWizard will add DDX and DDV calls here//}}AFX_DATA_MAP}BEGIN_MESSAGE_MAP(CSimpleThreadDemoDlg,CDialog)//{{AFX_MSG_MAP(CSimpleThreadDemoDlg)ON_WM_SYSCOMMAND()ON_WM_PAINT()ON_WM_QUERYDRAGICON()ON_BN_CLICKED(IDC_BUTTON_START,OnButtonStart)ON_BN_CLICKED(IDC_BUTTON_STOP,OnButtonStop)ON_WM_DESTROY()//}}AFX_MSG_MAPEND_MESSAGE_MAP()/////////////////////////////////////////////////////////////////////////////// CSimpleThreadDemoDlg message handlersBOOLCSimpleThreadDemoDlg::OnInitDialog(){CDialog::OnInitDialog();// Add About... menu item to system menu.// IDM_ABOUTBOX must be in the system command range.ASSERT((IDM_ABOUTBOX0xFFF0)IDM_ABOUTBOX);ASSERT(IDM_ABOUTBOX0xF000);CMenu*pSysMenuGetSystemMenu(FALSE);if(pSysMenu!NULL){CString strAboutMenu;strAboutMenu.LoadString(IDS_ABOUTBOX);if(!strAboutMenu.IsEmpty()){pSysMenu-AppendMenu(MF_SEPARATOR);pSysMenu-AppendMenu(MF_STRING,IDM_ABOUTBOX,strAboutMenu);}}// Set the icon for this dialog. The framework does this automatically// when the applications main window is not a dialogSetIcon(m_hIcon,TRUE);// Set big iconSetIcon(m_hIcon,FALSE);// Set small icon// TODO: Add extra initialization herereturnTRUE;// return TRUE unless you set the focus to a control}voidCSimpleThreadDemoDlg::OnSysCommand(UINT nID,LPARAM lParam){if((nID0xFFF0)IDM_ABOUTBOX){CAboutDlg dlgAbout;dlgAbout.DoModal();}else{CDialog::OnSysCommand(nID,lParam);}}// If you add a minimize button to your dialog, you will need the code below// to draw the icon. For MFC applications using the document/view model,// this is automatically done for you by the framework.voidCSimpleThreadDemoDlg::OnPaint(){if(IsIconic()){CPaintDCdc(this);// device context for paintingSendMessage(WM_ICONERASEBKGND,(WPARAM)dc.GetSafeHdc(),0);// Center icon in client rectangleintcxIconGetSystemMetrics(SM_CXICON);intcyIconGetSystemMetrics(SM_CYICON);CRect rect;GetClientRect(rect);intx(rect.Width()-cxIcon1)/2;inty(rect.Height()-cyIcon1)/2;// Draw the icondc.DrawIcon(x,y,m_hIcon);}else{CDialog::OnPaint();}}// The system calls this to obtain the cursor to display while the user drags// the minimized window.HCURSORCSimpleThreadDemoDlg::OnQueryDragIcon(){return(HCURSOR)m_hIcon;}// 线程函数UINTCSimpleThreadDemoDlg::ThreadProc(LPVOID pParam){THREAD_PARAM*pThreadParam(THREAD_PARAM*)pParam;CSimpleThreadDemoDlg*pDlgpThreadParam-pDlg;TRACE(线程开始运行\n);// 执行5次循环for(inti1;i5;i){// 检查停止标志if(pDlg-m_bStopThread){TRACE(线程接收到停止信号\n);break;}// 执行工作pDlg-DoThreadWork(i);// 休眠1秒Sleep(1000);}// 线程结束更新状态pDlg-m_bThreadActiveFALSE;// 清理参数deletepThreadParam;TRACE(线程运行结束\n);return0;}voidCSimpleThreadDemoDlg::DoThreadWork(intnIteration){TRACE(执行第%d项工作\n,nIteration);// 这里可以添加实际的工作代码}/////////////////////////////////////////////////////////////////////////////// 启动线程voidCSimpleThreadDemoDlg::OnButtonStart(){TRACE( 启动线程 \n);TRACE( 启动线程 \n);if(m_bThreadActive){AfxMessageBox(线程已经在运行);return;}// 重置事件if(m_hStopEvent){ResetEvent(m_hStopEvent);}// 初始化标志m_bStopThreadFALSE;// 不要停止m_bThreadActiveTRUE;// 线程正在运行// 创建线程参数// 创建线程参数THREAD_PARAM*pParamnewTHREAD_PARAM;pParam-pDlgthis;pParam-nCounter0;// 创建线程使用CREATE_SUSPENDED确保完全初始化后再运行CWinThread*pThreadAfxBeginThread(ThreadProc,pParam,THREAD_PRIORITY_NORMAL,0,CREATE_SUSPENDED);if(pThreadNULL){AfxMessageBox(创建线程失败);m_bThreadActiveFALSE;deletepParam;return;}// 保存句柄m_hThreadpThread-m_hThread;// 恢复线程运行pThread-ResumeThread();TRACE(线程启动成功ID: %d\n,pThread-m_nThreadID);AfxMessageBox(线程已启动);}/////////////////////////////////////////////////////////////////////////////// 停止线程voidCSimpleThreadDemoDlg::OnButtonStop(){TRACE( 停止线程 \n);if(!m_bThreadActive){AfxMessageBox(没有正在运行的线程);return;}// 安全终止线程SafeTerminateThread();AfxMessageBox(线程已停止);}voidCSimpleThreadDemoDlg::SafeTerminateThread(){TRACE(安全终止线程\n);if(!m_bThreadActive){TRACE(线程未激活\n);return;}// 1. 设置停止标志和事件m_bStopThreadTRUE;if(m_hStopEvent){SetEvent(m_hStopEvent);}// 2. 等待线程正常结束if(m_hThread){TRACE(等待线程正常退出...\n);// 等待3秒让线程正常退出DWORD dwWaitResultWaitForSingleObject(m_hThread,3000);if(dwWaitResultWAIT_OBJECT_0){TRACE(线程正常退出\n);}elseif(dwWaitResultWAIT_TIMEOUT){TRACE(线程超时未退出尝试强制终止\n);// 3. 强制终止最后手段// 警告这可能导致资源泄漏只在必要时使用if(!TerminateThread(m_hThread,0)){TRACE(强制终止失败错误代码: %d\n,GetLastError());}else{// 等待线程完全终止WaitForSingleObject(m_hThread,1000);TRACE(线程已被强制终止\n);}}// 4. 关闭句柄CloseHandle(m_hThread);m_hThreadNULL;}// 5. 重置状态m_bThreadActiveFALSE;m_bStopThreadFALSE;TRACE(安全终止线程完成\n);}voidCSimpleThreadDemoDlg::OnDestroy(){TRACE( 窗口销毁处理开始 \n);// 确保线程结束SafeTerminateThread();CDialog::OnDestroy();TRACE( 窗口销毁处理结束 \n);}CSimpleThreadDemoDlg::~CSimpleThreadDemoDlg(){// 确保线程结束if(m_bThreadActivem_hThread){// 设置停止事件SetEvent(m_hStopEvent);// 等待线程结束最多等待5秒DWORD dwWaitWaitForSingleObject(m_hThread,5000);if(dwWaitWAIT_TIMEOUT){// 如果线程在5秒内没有结束强制终止TerminateThread(m_hThread,0);TRACE(线程被强制终止\n);}// 关闭句柄CloseHandle(m_hThread);m_hThreadNULL;}// 关闭事件句柄if(m_hStopEvent){CloseHandle(m_hStopEvent);m_hStopEventNULL;}}Debug模式运行