多线程编程2 例程3-4(Win32 API)

来源:互联网 发布:登录淘宝帐号 编辑:程序博客网 时间:2024/05/01 16:47

来自:www.cnblogs.com/huqingyu/archive/2007/07/01/801923.html

四、Win32 API多线程编程例程

例程3 MultiThread3将演示如何传送一个指向结构体的指针参数。 

建立一个基于对话框的工程MultiThread3,在对话框IDD_MULTITHREAD3_DIALOG中加入一个编辑框IDC_MILLISECOND,一个按钮IDC_START,标题为“开始” ,一个进度条IDC_PROGRESS1; 
打开ClassWizard,为编辑框IDC_MILLISECOND添加int型变量m_nMilliSecond,为进度条IDC_PROGRESS1添加CProgressCtrl型变量m_ctrlProgress; 
在MultiThread3Dlg.h文件中添加一个结构的定义:

struct threadInfo
{
 UINT nMilliSecond;
 CProgressCtrl* pctrlProgress;
};

线程函数的声明: UINT ThreadFunc(LPVOID lpParam);

注意,二者应在类CMultiThread3Dlg的外部。 

在类CMultiThread3Dlg内部添加protected型变量:

HANDLE hThread;
DWORD ThreadID;

分别代表线程的句柄和ID。 
在MultiThread3Dlg.cpp文件中进行如下操作:

定义公共变量 threadInfo Info;
双击按钮IDC_START,添加相应消息处理函数:

void CMultiThread3Dlg::OnStart() 
{
 // TODO: Add your control notification handler code here

 UpdateData(TRUE);
 Info.nMilliSecond=m_nMilliSecond;
 Info.pctrlProgress=&m_ctrlProgress;

 hThread=CreateThread(NULL,
  0,
  (LPTHREAD_START_ROUTINE)ThreadFunc,
  &Info,
  0,
  &ThreadID);
/*
 GetDlgItem(IDC_START)->EnableWindow(FALSE);
 WaitForSingleObject(hThread,INFINITE);
 GetDlgItem(IDC_START)->EnableWindow(TRUE);
*/
}

在函数BOOL CMultiThread3Dlg::OnInitDialog()中添加语句:

{
 ……
 
 // TODO: Add extra initialization here
 m_ctrlProgress.SetRange(0,99);
 m_nMilliSecond=10;
 UpdateData(FALSE);
 return TRUE;  // return TRUE  unless you set the focus to a control
}

添加线程处理函数:

UINT ThreadFunc(LPVOID lpParam)

{
 threadInfo* pInfo=(threadInfo*)lpParam;
 for(int i=0;i<100;i++)
 {
  int nTemp=pInfo->nMilliSecond;

  pInfo->pctrlProgress->SetPos(i);

  Sleep(nTemp);
 }
 return 0;
}

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


例程4 MultiThread4
该例程测试在Windows下最多可创建线程的数目。 


建立一个基于对话框的工程MultiThread4,在对话框IDD_MULTITHREAD4_DIALOG中加入一个按钮IDC_TEST和一个编辑框IDC_COUNT,按钮标题为“测试” , 编辑框属性选中Read-only; 
在MultiThread4Dlg.cpp文件中进行如下操作:

添加公共变量volatile BOOL m_bRunFlag=TRUE; 
该变量表示是否还能继续创建线程。

添加线程函数: 

DWORD WINAPI threadFunc(LPVOID threadNum)
{
 while(m_bRunFlag)
 {
  Sleep(3000);
 }
 return 0;
}

只要 m_bRunFlag 变量为TRUE,线程一直运行。

双击按钮IDC_TEST,添加其响应消息函数:

void CMultiThread4Dlg::OnTest() 
{
 DWORD threadID;
 GetDlgItem(IDC_TEST)->EnableWindow(FALSE);
 long nCount=0;
 while(m_bRunFlag)
 {
  if(CreateThread(NULL,0,threadFunc,NULL,0,&threadID)==NULL)
  {
   m_bRunFlag=FALSE;
   break;
  }
  else
  {
   nCount++;
  }
 }

   //不断创建线程,直到再不能创建为止
 m_nCount=nCount;
 UpdateData(FALSE);
 Sleep(5000);
   //延时5秒,等待所有创建的线程结束
 GetDlgItem(IDC_TEST)->EnableWindow(TRUE);
    m_bRunFlag=TRUE;
}


原创粉丝点击