当前位置:松语文学 > 其他类型 >VC++_6.0程序设计从入门到精通最新章节 > VC++_6.0程序设计从入门到精通TXT下载
错误举报

第 47 章

  函数主要参数的意义。

  ? hThread:线程句柄。

  ? dwThreadAffinityMask:线程的相似xìng掩码。

  (2)SetThreadIdealProcessor 函数

  该函数用于为线程设定合适的处理器。当线程等待时间到,系统将在这个处理器上执行

  指定的线程,如果调用成功,将返回上一次的处理器数目或者MAXIMUM_PROCESSORS,

  否则返回-1。它的函数原型如下:

  DWORD SetThreadIdealProcessor(

  HANDLE hThread,

  枫叶文学网www.fywxw.com

  第9 章 多线程

  ·217·

  DWORD dwIdealProcessor

  );

  函数中主要参数的意义如下。

  ? hThread:线程句柄。

  ? dwIdealProcessor:可以执行指定线程的处理器数目,如果dwIdealProcessor 的值为

  MAXIMUM_PROCESSORS,说明该线程没有合适的处理器。

  9.实例:赛马程序

  实例9-1:赛马程序实例。源代码在光盘中“\09\实例9-1\Racing”目录下。

  为了帮助读者理解上述线程的基本知识,为后续高级技术打好基础,本节的最后给出一

  个多线程编程实例,模拟赛马的过程。

  (1)创建工程

  首先利用VC++6.0 的AppWizard 创建基于对话框的工程Racing,所有设置都采用默认选

  项。

  给对话框添加控件。包括1 个图片框、1 个组合框、3 个静态文本控件、3 个滑动杆控件、

  4 个按钮。控件的属xìng如表9-4 所示。

  表9-4 控件属xìng列表

  ID 属xìng或作用 控件类型

  IDC_RACINGBOX Frcom 图像框控件

  IDC_STATIC 速度设置 组合框控件

  IDC_STATIC 红马 静态文本控件

  IDC_STATIC 绿马 静态文本控件

  IDC_STATIC 蓝马 静态文本控件

  IDC_SLIDERR 红马速度 滑动杆控件

  IDC_SLIDERG 绿马速度 滑动杆控件

  IDC_SLIDERB 蓝马速度 滑动杆控件

  IDSTART 开始 按钮

  IDSTOP 停止 按钮

  IDPAUSE 暂停 按钮

  IDCANCEL 关闭 按钮

  (2)定义数据结构

  定义一个包含赛马信息的结构HORSE,代码如下:

  typedef struct _horse

  {

  HWND hWnd; // 窗口句柄

  int speed; // 马速度

  int x; // 马位置的x 坐标

  int y; // 马位置的y 坐标

  int size; // 马的大小, 用一个球来表示,size 是半径

  COLOR color; // 颜色

  CRect rect; // 表示跑道的矩形;

  枫叶文学网www.fywxw.com

  Visual C++ 6.0 程序设计从入门到精通

  ·218·

  }HORSE, *LPHORSE;

  (3)设置全局变量

  定义Mutex 句柄和名称的全局变量,代码如下:

  // Mutex 对象的名称

  char g_strRNcom[64] = "RedHorse";

  char g_strGNcom[64] = "GreenHorse";

  char g_strBNcom[64] = "BlueHorse";

  // Mutex 对象的句柄

  HANDLE g_hRMutex;

  HANDLE g_hGMutex;

  HANDLE g_hBMutex;

  (4)添加成员变量

  为CRacingDlg 添加3 个赛马信息的成员变量,包括红色、绿色、蓝色3 匹马。添加3

  个线程句柄的成员变量,以及一个线程是否暂停的成员变量,代码如下:

  // 定义红, 绿, 蓝3 匹马

  HORSE m_RedHorse;

  HORSE m_GreenHorse;

  HORSE m_BlueHorse;

  // 定义红, 绿, 蓝3 匹马各自线程的句柄

  HANDLE m_hRed;

  HANDLE m_hGreen;

  HANDLE m_hBlue;

  // 是否暂停状态

  BOOL m_bPaused;

  为控件添加成员变量,代码如下:

  // 设置红马的速度

  CSliderCtrl m_BSpeed;

  // 设置绿马的速度

  CSliderCtrl m_GSpeed;

  // 设置蓝马的速度

  CSliderCtrl m_RSpeed;

  // 跑道矩形

  CStatic m_RacingBox;

  (5)初始化信号量

  为CRacingDlg 添加初始化函数InitMutexes,用来创建Mutex 对象,代码如下:

  枫叶文学网www.fywxw.com

  第9 章 多线程

  ·219·

  BOOL CRacingDlg::InitMutexes()

  {

  // 初始化红马的Mutex

  g_hRMutex = CreateMutex(NULL, FALSE, g_strRNcom);

  if(g_hRMutex == NULL)

  {

  return FALSE;

  }

  // 初始化绿马的Mutex

  g_hGMutex = CreateMutex(NULL, FALSE, g_strGNcom);

  if(g_hGMutex == NULL)

  {

  return FALSE;

  }

  // 初始化蓝马的Mutex

  g_hBMutex = CreateMutex(NULL, FALSE, g_strBNcom);

  if(g_hBMutex == NULL)

  {

  return FALSE;

  }

  return TRUE;

  }

  (6)初始化控件

  为CRacingDlg 添加初始化函数InitDlgItem,用来初始化对话框的控件,代码如下:

  void CRacingDlg::InitDlgItem()

  {

  // 设置滑动杆的范围和初始位置

  m_RSpeed.SetRange(10, 100);

  m_RSpeed.SetPos(50);

  m_GSpeed.SetRange(10, 100);

  m_GSpeed.SetPos(50);

  m_BSpeed.SetRange(10, 100);

  m_BSpeed.SetPos(50);

  // 暂停按钮的初始状态

  m_bPaused = FALSE;

  枫叶文学网www.fywxw.com

  Visual C++ 6.0 程序设计从入门到精通

  ·220·

  CButton* pBtn;

  // 开始按钮的状态为TRUE

  pBtn = (CButton*)GetDlgItem(IDSTART);

  pBtn->EnableWindow(TRUE);

  // 暂停按钮的状态为TRUE

  pBtn = (CButton*)GetDlgItem(IDPAUSE);

  pBtn->EnableWindow(FALSE);

  // 结束按钮的状态为TRUE

  pBtn = (CButton*)GetDlgItem(IDSTOP);

  pBtn->EnableWindow(FALSE);

  }

  (7)实现线程函数

  实现线程函数ThreadProc,代码如下:

  extern DWORD WINAPI ThreadProc(LPVOID lpParam)

  {

  LPHORSE lpHorse;

  HANDLE hMutex;

  lpHorse = LPHORSE(lpParam);

  // 打开Mutex 对象

  if( lpHorse->color == RED )

  {

  hMutex = ::OpenMutex(MUTEX_ALL_ACCESS, FALSE, g_strRNcom);

  }

  else if ( lpHorse->color == GREEN )

  {

  hMutex = ::OpenMutex(MUTEX_ALL_ACCESS, FALSE, g_strGNcom);

  }

  else if ( lpHorse->color == BLUE )

  {

  hMutex = ::OpenMutex(MUTEX_ALL_ACCESS, FALSE, g_strBNcom);

  }

  枫叶文学网www.fywxw.com

  第9 章 多线程

  ·221·

  else

  return 1; // 颜色不对

  if( hMutex == NULL )

  {

  AfxMessageBox("open Mutex error...");

  return 1;

  }

  // 循环,等待信号

  while ( true )

  {

  if ( WaitForSingleObject(hMutex, INFINITE) == WAIT_FAILED )

  {

  continue;

  }

  // 马前进

  if ( lpHorse->x < lpHorse->rect.right )

  {

  lpHorse->x ++;

  }

  // 重绘窗口

  InvalidateRect(lpHorse->hWnd, lpHorse->rect, TRUE);

  // 释放Mutex

  ReleaseMutex(hMutex);

  // 等待, 速度快的等待时间短

  Sleep(lpHorse->speed);

  }

  return 0;

  }

  (8)初始化对话框

  改写对话框的OnInitDialog,进行必要的初始化,代码如下:

  BOOL CRacingDlg::OnInitDialog()

  枫叶文学网www.fywxw.com

  Visual C++ 6.0 程序设计从入门到精通

  ·222·

  {

  ……

  // TODO: Add extra initialization here

  // 初始化Mutex

  InitMutexes();

  // 初始化对话框

  InitDlgItem();

  ……

  }

  (9)绘制场景

  为CRacingDlg 添加成员函数DrawScene,用来绘制赛马的场景,代码如下:

  // 绘制场景的函数

  void CRacingDlg::DrawScene(CPaintDC * pDC)

  {

  CRect rect;

  CBrush redBrush(RGB(255, 0, 0));

  CBrush greenBrush(RGB(0, 255, 0));

  CBrush blueBrush(RGB(0, 0, 255));

  CBrush* oldBrush;

  m_RacingBox.GetClientRect(rect);

  m_RacingBox.ClientToScreen(rect);

  pDC->Rectangle(rect);

  // 绘制红马

  if( m_hRed )

  {

  pDC->Rectangle(m_RedHorse.rect);

  oldBrush = pDC->SelectObject(&redBrush);

  pDC->Ellipse(m_RedHorse.x-m_RedHorse.size, m_RedHorse.y-m_RedHorse.size,

  m_RedHorse.x+m_RedHorse.size, m_RedHorse.y+m_RedHorse.size);

  pDC->SelectObject(oldBrush);

  }

  // 绘制绿马

  if( m_hGreen )

  枫叶文学网www.fywxw.com

  第9 章 多线程

  ·223·

  {

  pDC->Rectangle(m_GreenHorse.rect);

  oldBrush = pDC->SelectObject(&greenBrush);

  pDC->Ellipse(m_GreenHorse.x-m_GreenHorse.size, m_GreenHorse.y-m_GreenHorse.size,

  m_GreenHorse.x+m_GreenHorse.size, m_GreenHorse.y+m_GreenHorse.size);

  pDC->SelectObject(oldBrush);

  }

  // 绘制蓝马

  if( m_hBlue )

  {

  pDC->Rectangle(m_BlueHorse.rect);

  oldBrush = pDC->SelectObject(&blueBrush);

  pDC->Ellipse(m_BlueHorse.x-m_BlueHorse.size, m_BlueHorse.y-m_BlueHorse.size,

  m_BlueHorse.x+m_BlueHorse.size, m_BlueHorse.y+m_BlueHorse.size);

  pDC->SelectObject(oldBrush);

  }

  }

  改写CRacingDlg 的OnPaint 函数,调用DrawScene,代码如下:

  void CRacingDlg::OnPaint()

  {

  if (IsIconic())

  {

  ……

  }

  else

  {

  CPaintDC dc(this); // device context for painting

  CDialog::OnPaint();

  // 绘制场景

  DrawScene(&dc);

  }

  }

  (10)响应“开始”按钮

  响应“开始”按钮,用来启动线程,代码如下:

  void CRacingDlg::OnStart()

  {

  // TODO: Add your control notification handler code here

  枫叶文学网www.fywxw.com

  Visual C++ 6.0 程序设计从入门到精通

  ·224·

  DWORD tID;

  DWORD code;

  CRect clientrect;

  CRect racingrect;

  GetClientRect(clientrect);

  ClientToScreen(clientrect);

  m_RacingBox.GetClientRect(racingrect);

  m_RacingBox.ClientToScreen(racingrect);

  racingrect -= clientrect.TopLeft();

  if( !GetExitCodeThread(m_hRed, &code) ||

  code != STILL_ACTIVE )

  {

  // 填写红马信息

  m_RedHorse.hWnd = this->GetSafeHwnd();

  m_RedHorse.color = RED;

  m_RedHorse.speed = m_RSpeed.GetPos();

  m_RedHorse.size = 10;

  m_RedHorse.rect.TopLeft() = racingrect.TopLeft();

  m_RedHorse.rect.right = m_RedHorse.rect.TopLeft().x + racingrect.Width();

  m_RedHorse.rect.bottom = m_RedHorse.rect.TopLeft().y + racingrect.Height()/3;

  m_RedHorse.x = m_RedHorse.rect.left + m_RedHorse.size;

  m_RedHorse.y = m_RedHorse.rect.top + m_RedHorse.rect.Height()/2;

  // 创建红马线程

  m_hRed = CreateThread(NULL, 0, ThreadProc, &m_RedHorse, 0, &tID);

  if(m_hRed == NULL)

  {

  AfxMessageBox("创建线程失败");

  }

  }

  if( !GetExitCodeThread(m_hGreen, &code) ||

  code != STILL_ACTIVE )

  {

  枫叶文学网www.fywxw.com

  第9 章 多线程

  ·225·

  // 填写绿马信息

  m_GreenHorse.hWnd = this->GetSafeHwnd();

  m_GreenHorse.color = GREEN;

  m_GreenHorse.speed = m_GSpeed.GetPos();

  m_GreenHorse.size = 10;

  m_GreenHorse.rect.TopLeft() = racingrect.TopLeft()+CPoint(0, racingrect.Height()/3);

  m_GreenHorse.rect.right = m_GreenHorse.rect.TopLeft().x + racingrect.Width();

  m_GreenHorse.rect.bottom = m_GreenHorse.rect.TopLeft().y + racingrect.Height()/3;

  m_GreenHorse.x = m_GreenHorse.rect.left + m_GreenHorse.size;

  m_GreenHorse.y = m_GreenHorse.rect.top + m_GreenHorse.rect.Height()/2;

  // 创建绿马线程

  m_hGreen = CreateThread(NULL, 0, ThreadProc, &m_GreenHorse, 0, &tID);

  if(m_hGreen == NULL)

  {

  AfxMessageBox("创建线程失败");

  }

  }

  if( !GetExitCodeThread(m_hBlue, &code) ||

  code != STILL_ACTIVE )

  {

  // 填写蓝马信息

  m_BlueHorse.hWnd = this->GetSafeHwnd();

  m_BlueHorse.color = BLUE;

  m_Blue

  松语文学免费小说阅读_www.16sy.com