WIN32 API多线程编码--参数传递(二)

           在多线程编程中,常常会遇到需要给线程函数传递参数,传送一个结构体给一个线程函数也是可能的,可以通过传送一个指向结构体的指针参数来完成。先定义一个结构体:

struct ThreadParams
{
	UINT nMilliSecond;
	CProgressCtrl *pCtrlProgress;
};
         用实例来说明,新建一个CThreadPassParameterDlg的对话框工程, 在对话框中加入一个编辑框  IDC_MILLISECOND ,一个按钮  IDC_START ,标题为 开始 ”  ,一个进度条  IDC_PROGRESS1 ;打开  ClassWizard ,为编辑框  IDC_MILLISECOND  添加  int  型变量  m_nMilliSecond ,为进度条  IDC_PROGRESS1  添加  CProgressCtrl  型变量  m_ctrlProgress

     在CThreadPassParameterDlg的头文件加(类的外部):

struct ThreadParams
{
	UINT nMilliSecond;
	CProgressCtrl *pCtrlProgress;
};

DWORD ThreadFun(LPVOID lpParam);
     并在类内定义:

	HANDLE m_hThread;
	DWORD m_threadID;
	ThreadParams m_params;
在函数 BOOL CThreadPassParameterDlg::OnInitDialog() 中添加语句:

	m_ctrlProgress.SetRange(0, 99);
	m_nMilliSecond = 10;
	UpdateData(FALSE);
CThreadPassParameterDlg类实现的外面添加:

DWORD ThreadFun(LPVOID lpParam)
{
	ThreadParams* param = (ThreadParams*)lpParam;
	for ( int i=0; i<100; i++)
	{
		int nTemp = param->nMilliSecond;
		param->pCtrlProgress->SetPos(i);
		Sleep(nTemp);
	}
	
	return (DWORD)0;
}
添加开始按钮的响应函数:

void CThreadPassParameterDlg::OnBtnStart() 
{
	UpdateData(TRUE);
	m_params.nMilliSecond = m_nMilliSecond;
	m_params.pCtrlProgress = &m_ctrlProgress;

	m_hThread = CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE)ThreadFun, &m_params, 0, &m_threadID);
	
	/*
	GetDlgItem(IDC_BTN_START)->EnableWindow(FALSE);
	WaitForSingleObject(m_hThread, INFINITE);
	GetDlgItem(IDC_BTN_START)->EnableWindow(TRUE);
	*/	
}
    顺便解释下WaitForSingleObject函数, WaitForSingleObject  函数,其函数原型为:

DWORD WaitForSingleObject(HANDLE hHandle,DWORD dwMilliseconds);
hHandle 为要监视的对象(一般为同步对象,也可以是线程)的句柄;

dwMilliseconds 为 hHandle 对象所设置的超时值,单位为毫秒;

当在某一线程中调用该函数时,线程暂时挂起,系统监视 hHandle 所指向的对象的状态 。

如果在挂起的 dwMilliseconds 毫秒内,线程所等待的对象变为有信号状态,则该函数立即返回;如果超时时间已经到达dwMilliseconds 毫秒,但 hHandle 所指向的对象还没有变成有信号状态,函数照样返回。参数 dwMilliseconds 有两个具有特殊意义的值:和 INFINITE 。若为 0,则该函数立即返回;若为 INFINITE,则线程一直被挂起,直到 hHandle 所指向的对象变为有信号状态时为止。

     如果你在 void CThreadPassParameterDlg::OnStart() 函数中添加/* */语 句 ,编译运行你就会发现进度条不进行刷新,主线程也停止了反应。什么原因呢?这是因为WaitForSingleObject 函数等待子线程( ThreadFunc )结束时,导致了线程死锁。因为WaitForSingleObject 函数会将主线程挂起(任何消息都得不到处理),而子线程 ThreadFunc正在设置进度条,一直在等待主线程将刷新消息处理完毕返回才会检测通知事件。这样两个线程都在互相等待,死锁发生了,编程时应注意避免。

你可能感兴趣的:(编程语言c++)