登录  
 加关注
查看详情
   显示下一条  |  关闭
温馨提示!由于新浪微博认证机制调整,您的新浪微博帐号绑定已过期,请重新绑定!立即重新绑定新浪微博》  |  关闭

面包会有的

... ...

 
 
 

日志

 
 

MFC的工作者线程示例[张]  

2011-03-17 22:42:01|  分类: VC++ |  标签: |举报 |字号 订阅

  下载LOFTER 我的照片书  |

MFC的工作者线程示例 - 加菲 -  .

 初始状态

 

MFC的工作者线程示例 - 加菲 -  .

 四个线程先后开始运行,如图,会更新列表控件中的1234行的第2栏的值(第0行忽略)

 

MFC的工作者线程示例 - 加菲 -  .

 先点第一个线程的按钮开始,然后点开始全部服务,实际上第一个线程函数被运行了两次,后三个线程只运行一次。

 

 

代码段:

 class threadStruct
 {
 public:
  int wm;
  int iStopThread;
 public:
  threadStruct();
  ~threadStruct();


 };

 


class CServerDlg : public CDialog
{
// Construction
public:

 CWinThread* pThread1,*pThread2,*pThread3,*pThread4;
 int iStopThread1,iStopThread2,iStopThread3,iStopThread4;
 threadStruct thdStruct[5];

 

=============

BOOL CServerDlg::OnInitDialog()
{
 CDialog::OnInitDialog();

 // Add "About..." menu item to system menu.

 // IDM_ABOUTBOX must be in the system command range.
 ASSERT((IDM_ABOUTBOX & 0xFFF0) == IDM_ABOUTBOX);
 ASSERT(IDM_ABOUTBOX < 0xF000);

 CMenu* pSysMenu = GetSystemMenu(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 application's main window is not a dialog
 SetIcon(m_hIcon, TRUE);   // Set big icon
 SetIcon(m_hIcon, FALSE);  // Set small icon
 
 // TODO: Add extra initialization here

 //设置风格
 LONG lStyle;
 lStyle = GetWindowLong(m_listServerThread.m_hWnd, GWL_STYLE);//获取当前窗口style
 lStyle &= ~LVS_TYPEMASK; //清除显示方式位
 lStyle |= LVS_REPORT; //设置style
 SetWindowLong(m_listServerThread.m_hWnd, GWL_STYLE, lStyle);//设置style

 DWORD dwStyle = m_listServerThread.GetExtendedStyle();
 dwStyle |= LVS_EX_FULLROWSELECT;//选中某行使整行高亮(只适用与report风格的listctrl)
 dwStyle |= LVS_EX_GRIDLINES;//网格线(只适用与report风格的listctrl)
 //dwStyle |= LVS_EX_CHECKBOXES;//item前生成checkbox控件
 m_listServerThread.SetExtendedStyle(dwStyle); //设置扩展风格

 m_listServerThread.InsertColumn( 0, "ID", LVCFMT_LEFT, 50 );//插入列,将宽度设置成0,在外观上就看不到此列,用来存放会员号
 m_listServerThread.InsertColumn( 1, "线程", LVCFMT_LEFT, 80 );
 m_listServerThread.InsertColumn( 2, "值", LVCFMT_LEFT, 80 );
 m_listServerThread.InsertColumn( 3, "-", LVCFMT_LEFT, 60 );
 m_listServerThread.InsertColumn( 4, "-", LVCFMT_LEFT, 60 );
 m_listServerThread.InsertColumn( 5, "-", LVCFMT_LEFT, 160 );
 m_listServerThread.InsertColumn( 6, "-", LVCFMT_LEFT, 160 );

 m_listServerThread.InsertItem(0, 0);//插入行
 m_listServerThread.SetItemText(0, 1, "0");
 m_listServerThread.SetItemText(0, 2, "x");//设置数据
 m_listServerThread.SetItemText(0, 3, "50");
 m_listServerThread.SetItemText(0, 4, "5");
 m_listServerThread.SetItemText(0, 5, "2010-12-1");
 m_listServerThread.SetItemText(0, 6, "2010-12-1");


 m_listServerThread.InsertItem(1, 0);//插入行
 m_listServerThread.SetItemText(1, 1, "1");
 m_listServerThread.SetItemText(1, 2, "x");//设置数据
 m_listServerThread.SetItemText(1, 3, "50");
 m_listServerThread.SetItemText(1, 4, "5");
 m_listServerThread.SetItemText(1, 5, "2010-12-1");
 m_listServerThread.SetItemText(1, 6, "2010-12-1");

 m_listServerThread.InsertItem(2, 0);//插入行
 m_listServerThread.SetItemText(2, 1, "2");
 m_listServerThread.SetItemText(2, 2, "x");//设置数据
 m_listServerThread.SetItemText(2, 3, "50");
 m_listServerThread.SetItemText(2, 4, "5");
 m_listServerThread.SetItemText(2, 5, "2010-12-1");
 m_listServerThread.SetItemText(2, 6, "2010-12-1");

 m_listServerThread.InsertItem(3, 0);//插入行
 m_listServerThread.SetItemText(3, 1, "3");
 m_listServerThread.SetItemText(3, 2, "x");//设置数据
 m_listServerThread.SetItemText(3, 3, "50");
 m_listServerThread.SetItemText(3, 4, "5");
 m_listServerThread.SetItemText(3, 5, "2010-12-1");
 m_listServerThread.SetItemText(3, 6, "2010-12-1");

 m_listServerThread.InsertItem(4, 0);//插入行
 m_listServerThread.SetItemText(4, 1, "4");
 m_listServerThread.SetItemText(4, 2, "x");//设置数据
 m_listServerThread.SetItemText(4, 3, "50");
 m_listServerThread.SetItemText(4, 4, "5");
 m_listServerThread.SetItemText(4, 5, "2010-12-1");
 m_listServerThread.SetItemText(4, 6, "2010-12-1");


 (this->GetDlgItem(IDC_BUTTON6))->EnableWindow(false); 
 (this->GetDlgItem(IDC_BUTTON7))->EnableWindow(false);
 (this->GetDlgItem(IDC_BUTTON8))->EnableWindow(false);
 (this->GetDlgItem(IDC_BUTTON9))->EnableWindow(false);
 SetTimer(1,1000,NULL);
 
 return TRUE;  // return TRUE  unless you set the focus to a control
}

 

 

 

================


UINT ThreadFunc1(LPVOID lpParam)
{
 threadStruct* pwwm=(threadStruct*)lpParam;
 
 int bm;
 bm=1;
 while (bm)
 {
  
  if (pwwm->iStopThread==1 )
  {
   bm=0;
  }
  (pwwm->wm)++;
  if ((pwwm->wm) > 99)
  {
  (pwwm->wm)=0;
  }
  Sleep(2000);
 }
 return 0;

}


void CServerDlg::OnBtnStartserver()
{
 // TODO: Add your control notification handler code here
 OnButton1();
 OnButton2();
 OnButton3();
 OnButton4();

}

void CServerDlg::OnTimer(UINT nIDEvent)
{
 // TODO: Add your message handler code here and/or call default
 switch (nIDEvent)
 {
 case 1:
  {
   //更新列表框
   CString str1;
   str1.Format("%d",thdStruct[1].wm);
   m_listServerThread.SetItemText(1,2,TEXT(str1));//将该行的列值修改为1
   m_listServerThread.Update(1);

   str1.Format("%d",thdStruct[2].wm);
   m_listServerThread.SetItemText(2,2,TEXT(str1));//将该行的列值修改为1
   m_listServerThread.Update(1);

   str1.Format("%d",thdStruct[3].wm);
   m_listServerThread.SetItemText(3,2,TEXT(str1));//将该行的列值修改为1
   m_listServerThread.Update(1);

   str1.Format("%d",thdStruct[4].wm);
   m_listServerThread.SetItemText(4,2,TEXT(str1));//将该行的列值修改为1
   m_listServerThread.Update(1);

 


  }
 case 2:
  {
  }
 };
 CDialog::OnTimer(nIDEvent);
}

void CServerDlg::OnDestroy()
{
 CDialog::OnDestroy();
 
 // TODO: Add your message handler code here
 KillTimer(1);
}

void CServerDlg::OnBtnStopserver()
{
 // TODO: Add your control notification handler code here
 OnButton6();
 OnButton7();
 OnButton8();
}

void CServerDlg::OnButton1() //开始线程

{
 // TODO: Add your control notification handler code here
 pThread1=AfxBeginThread(ThreadFunc1,&thdStruct[1]); 
 (this->GetDlgItem(IDC_BUTTON1))->EnableWindow(false);
 (this->GetDlgItem(IDC_BUTTON6))->EnableWindow(true);
}

void CServerDlg::OnButton2() //开始线程

{
 // TODO: Add your control notification handler code here
 pThread2=AfxBeginThread(ThreadFunc1,&thdStruct[2]); 
 (this->GetDlgItem(IDC_BUTTON2))->EnableWindow(false);
 (this->GetDlgItem(IDC_BUTTON7))->EnableWindow(true);
}

void CServerDlg::OnButton3() //开始线程
{
 // TODO: Add your control notification handler code here
 pThread3=AfxBeginThread(ThreadFunc1,&thdStruct[3]); //在MFC中,一般由全局函数AfxBeginThread来创建并初始化一个线程的运行
            //创建工作者线程,程序员不必从CWinThread派生新的线程类,只需要提供一个线程入口,也就是一个函数地址就可以了。
            //在工作者线程被启动后会转入该函数,并且函数退出时线程就会结束。
            //线程函数的固定形式是,UINT Function(LPVOID pParam)
 (this->GetDlgItem(IDC_BUTTON3))->EnableWindow(false);            //CWinThread* AFXAPI AfxBeginThread(......)
 (this->GetDlgItem(IDC_BUTTON8))->EnableWindow(true);
}

void CServerDlg::OnButton4() //开始线程

{
 // TODO: Add your control notification handler code here
 pThread4=AfxBeginThread(ThreadFunc1,&thdStruct[4]); 
 (this->GetDlgItem(IDC_BUTTON4))->EnableWindow(false);
 (this->GetDlgItem(IDC_BUTTON9))->EnableWindow(true); 
}

void CServerDlg::OnButton6() //停止线程,通过将传给线程的类对象的一个成员设为1来达到,使线程函数中的循环条件失效而退出线程函数
{
 // TODO: Add your control notification handler code here
 thdStruct[1].iStopThread=1;
 (this->GetDlgItem(IDC_BUTTON6))->EnableWindow(false);
 (this->GetDlgItem(IDC_BUTTON1))->EnableWindow(true);
}

void CServerDlg::OnButton7()  //停止线程
{
 // TODO: Add your control notification handler code here
 thdStruct[2].iStopThread=1;
 (this->GetDlgItem(IDC_BUTTON7))->EnableWindow(false);
 (this->GetDlgItem(IDC_BUTTON2))->EnableWindow(true);
}

void CServerDlg::OnButton8()  //停止线程
{
 // TODO: Add your control notification handler code here
 thdStruct[3].iStopThread=1;
 (this->GetDlgItem(IDC_BUTTON8))->EnableWindow(false);
 (this->GetDlgItem(IDC_BUTTON3))->EnableWindow(true);
}

void CServerDlg::OnButton9()  //停止线程
{
 // TODO: Add your control notification handler code here
 thdStruct[4].iStopThread=1;
 (this->GetDlgItem(IDC_BUTTON9))->EnableWindow(false);
 (this->GetDlgItem(IDC_BUTTON4))->EnableWindow(true); 
}

本示例为本人设计,变量命名不规范,主要是想试验一下MFC工作者线程的运行情况。

把书本上最关键的几句摘录如下:

 

工作者线程的创建,程序员不必从CWinThread派生新的线程类(用户界面线程需派生),只需要提供一个线程入口中,也就是一个函数地址即可,在工作者线程被启动后会转入该函数,并且函数退出时线程就会结束。该线程函数的固定形式为:UINT Function(LPVOID pParam)

注意线程函数的参数为LPVOID,可以根据参数的类型进行强制转换,然后就可以通过强制转换得到的指针来访问传来的参数的内存空间。可以传入类对象或结构对象,或者内置数据类型。

在本例中,单击开始按钮,可开始一个线程,如果对同一按钮多次单击(每次单击后不禁用按钮,或者不同的按钮重复调用一个函数),会导致意外的开始新的线程。在本例中,每次递增的值可能是1,2,或4,就反应了这一点。

要退出一个工作者线程,需要强制退出线程函数。

自定义的类对象中的第二个变量,就是用来强制中止线程而定义的。

  评论这张
 
阅读(3154)| 评论(0)

历史上的今天

在LOFTER的更多文章

评论

<#--最新日志,群博日志--> <#--推荐日志--> <#--引用记录--> <#--博主推荐--> <#--随机阅读--> <#--首页推荐--> <#--历史上的今天--> <#--被推荐日志--> <#--上一篇,下一篇--> <#-- 热度 --> <#-- 网易新闻广告 --> <#--右边模块结构--> <#--评论模块结构--> <#--引用模块结构--> <#--博主发起的投票-->
 
 
 
 
 
 
 
 
 
 
 
 
 
 

页脚

网易公司版权所有 ©1997-2018