快3网上购买

ccriticalsection释放_ccriticalsection 使用_ccriticalsection 调用 2

电脑杂谈  发布时间:2019-09-03 13:03:13  来源:网络整理

ccriticalsection 使用_ccriticalsection 调用 2次_ccriticalsection释放

原文地址:(转)

(转)

一般而言,应用程序中的一个次要线程总是为主线程执行特定的任务,这样,主线程和次要线程间一定有一个信息释放的渠道,也就是主线程和次要线程间要进行通信。这种线程间的通信不可是无法规避的,而且在多线程编程中也有复杂和经常的,下面将进行说明。

使用全局变量进行通信

由于属于同一个进程的各个线程共享操作系统分配该进程的资源,故解决线程间通信最简洁的一种方法是使用全局变量。对于标准类别的全局函数,我们建议使用volatile 修饰符,它告诉编译器无需对该函数作任何的改进,即无需将它放在一个寄存器中,并且该值可被内部改变。如果线程间所需传递的信息较复杂,我们可以定义一个结构,通过释放指向该结构的指针进行释放信息。

使用自定义消息

我们可以在一个线程的执行变量中向另一个线程发送自定义的消息来超过通信的目的。一个线程向另外一个线程发送消息是借助操作系统实现的。利用Windows操作系统的消息驱动机制,当一个线程发出一条消息时,操作系统首先接收到该消息,然后把该消息转发给目标线程,接收消息的线程需要尚未完善了消息循环。

例程7 MultiThread7

快3网上购买该实例演示了怎样使用自定义消息进行轮询间通讯。首先,主线程向CCalculateThread线程发送消息WM_CALCULATE,CCalculateThread线程收到消息后进行计算,再向主线程发送WM_DISPLAY消息,主线程收到该消息后显示计算结果。

建立一个基于对话框的项目MultiThread7,在对话框IDD_MULTITHREAD7_DIALOG中加入三个单选按钮IDC_RADIO1,IDC_RADIO2,IDC_RADIO3,标题分别为1+2+3+4+......+10,1+2+3+4+......+50,1+2+3+4+......+100。加入图标IDC_SUM,标题为“求和”。加入标签框IDC_STATUS,属性选中“边框”;在MultiThread7Dlg.h中定义如下变量:

protected:
	int nAddend;
代表加数的大小。

分别双击三个单选按纽,添加消息响应函数:


void CMultiThread7Dlg::OnRadio1()   
{  
    nAddend=10;  
}  
  
void CMultiThread7Dlg::OnRadio2()   
{  
    nAddend=50;  
      
}  
  
void CMultiThread7Dlg::OnRadio3()   
{  
    nAddend=100;  
      
} 

并在OnInitDialog函数中完成相应的初始化工作:


BOOLCMultiThread7Dlg::OnInitDialog(){……((CButton*)GetDlgItem(IDC_RADIO1))->SetCheck(TRUE);nAddend=10;……

在MultiThread7Dlg。h中添加:


#include"CalculateThread.h"#defineWM_DISPLAYWM_USER+2classCMultiThread7Dlg:publicCDialog{//Constructionpublic:CMultiThread7Dlg(CWnd*pParent=NULL);//standardconstructorCCalculateThread*m_pCalculateThread;……protected:intnAddend;LRESULTOnDisplay(WPARAMwParam,LPARAMlParam);……在MultiThread7Dlg.cpp中添加:BEGIN_MESSAGE_MAP(CMultiThread7Dlg,CDialog)……ON_MESSAGE(WM_DISPLAY,OnDisplay)END_MESSAGE_MAP()LRESULTCMultiThread7Dlg::OnDisplay(WPARAMwParam,LPARAMlParam){intnTemp=(int)wParam;SetDlgItemInt(IDC_STATUS,nTemp,FALSE);return0;}

以上代码并且主线程类CMultiThread7Dlg可以处理WM_DISPLAY消息,即在IDC_STATUS标签框中显示计算结果。 双击图标IDC_SUM,添加消息响应函数:


voidCMultiThread7Dlg::OnSum(){m_pCalculateThread=(CCalculateThread*)AfxBeginThread(RUNTIME_CLASS(CCalculateThread));Sleep(500);m_pCalculateThread->PostThreadMessage(WM_CALCULATE,nAddend,NULL);}

OnSum()函数的作用是建立CalculateThread线程,延时给该线程发送WM_CALCULATE消息。 右击工程并选中“New Class…”为工程添加基类为 CWinThread 派生线程类 CCalculateThread。

在文件CalculateThread.h 中添加


#defineWM_CALCULATEWM_USER+1classCCalculateThread:publicCWinThread{……protected:afx_msgLONGOnCalculate(UINTwParam,LONGlParam);……在文件CalculateThread。cpp中添加LONGCCalculateThread::OnCalculate(UINTwParam,LONGlParam){intnTmpt=0;for(inti=0;i<=(int)wParam;i++){nTmpt=nTmpt+i;}Sleep(500);::PostMessage((HWND)(GetMainWnd()->GetSafeHwnd()),WM_DISPLAY,nTmpt,NULL);return0;}BEGIN_MESSAGE_MAP(CCalculateThread,CWinThread)//{{AFX_MSG_MAP(CCalculateThread)//NOTE-theClassWizardwilladdandremovemappingmacroshere。//}}AFX_MSG_MAPON_THREAD_MESSAGE(WM_CALCULATE,OnCalculate)//和主线程对比,注意他们的差别END_MESSAGE_MAP()

在CalculateThread。cpp文件的开头添加一条:

#include "MultiThread7Dlg.h"
以上代码为CCalculateThread类添加了 WM_CALCULATE 消息,消息的响应函数是 OnCalculate,其用途是按照参数 wParam 的值,进行累加,累加结果在临时变量nTmpt中,延时0.5秒,向主线程发送WM_DISPLAY消息进行显示,nTmpt作为参数传递。

编译并运行该实例,体会怎么程间释放消息。

虽然多线程能给我们带给好处,但是还有不少问题必须解决。例如,对于像磁盘驱动器这样独占性系统资源,由于线程可以执行进程的任何代码段ccriticalsection释放,且线程的运行是由平台调度自动完成的,具有必定的不确定性,因此就有也许发生两个线程同时对磁盘驱动器进行操作,从而发生操作出错;又比如,对于银行平台的计算机来说,可能使用一个线程来升级其库,而用此外一个线程来调用以响应储户的应该,极有也许读的轮询调用的是未完全升级的,因为也许在读的之后只有一部分数据被升级过。

快3网上购买使隶属于同一进程的各线程协调一致地工作称为线程的同步。MFC提供了多种同步对象,下面我们只介绍最常见的四种:

通过这种类,我们可以非常易于地做到线程同步。

A、使用 CCriticalSection 类

当多个线程访问一个独占性共享资源时,可以使用“临界区”对象。任一时刻只有一个线程可以拥有临界区对象,拥有临界区的轮询可以访问被保护出来的资源或代码段,其他希望处于临界区的线程将被挂起等待,直到拥有临界区的线程放弃临界区时为止,这样就确保了不会在同一时刻发生多个线程访问共享资源。

CCriticalSection类的用法比较简单,步骤如下:

定义CCriticalSection类的一个全局对象(以使各个线程均能访问),如CCriticalSection critical_section;在访问必须保护的资源或代码之前,调用CCriticalSection类的成员Lock()获得临界区对象:

critical_section.Lock();
在句柄中读取该变量来使线程获取它所请求的临界区。如果这时没有其它线程占有临界区对象,则读取Lock()的轮询获取临界区;否则,线程将被挂起,并放在到一个系统队列中期待,直到当前拥有临界区的线程释放了临界区时为止。访问临界区完毕后,使用CCriticalSection的成员变量Unlock()来释放临界区:
critical_section.Unlock();
再通俗一点讲,就是线程A执行到critical_section.Lock();语句时,如果其他线程(B)正在执行critical_section.Lock();语句后且critical_section. Unlock();语句前的语句时,线程A就会等待,直到线程B执行完critical_section. Unlock();语句,线程A才会再次执行。

下面再借助一个实例进行演示表明。

例程8 MultiThread8

建立一个基于对话框的项目MultiThread8,在对话框IDD_MULTITHREAD8_DIALOG中加入两个按钮和两个编辑框控件,两个按钮的ID分别为IDC_WRITEW和IDC_WRITED,标题分别为“写‘W’”和“写‘D’”;两个编辑框的ID分别为IDC_W和IDC_D,属性都选中Read-only;在MultiThread8Dlg。h文件中声明两个线程变量:

UINT WriteW(LPVOID pParam);
UINT WriteD(LPVOID pParam);
使用ClassWizard分别给IDC_W和IDC_D添加CEdit类变量m_ctrlW和m_ctrlD;在MultiThread8Dlg.cpp文件中添加如下内容:
为了文件中能够正确使用同步类,在文件开头添加:
#include "afxmt.h"
定义临界区和一个字符数组,为了能够在不同线程间使用,定义为全局变量:
CCriticalSection critical_section;
char g_Array[10];
添加线程函数:
UINT WriteW(LPVOID pParam)
{
 CEdit *pEdit=(CEdit*)pParam;
 pEdit->SetWindowText("");
 critical_section.Lock();
 //锁定临界区,其它线程遇到critical_section.Lock();语句时要等待
 //直至执行critical_section.Unlock();语句
 for(int i=0;i<10;i++)
 {
  g_Array[i]=''W'';
     pEdit->SetWindowText(g_Array);
  Sleep(1000);
 }
 critical_section.Unlock();
 return 0;
}
UINT WriteD(LPVOID pParam)
{
 CEdit *pEdit=(CEdit*)pParam;
 pEdit->SetWindowText("");
 critical_section.Lock();
 //锁定临界区,其它线程遇到critical_section.Lock();语句时要等待
 //直至执行critical_section.Unlock();语句
 for(int i=0;i<10;i++)
 {
  g_Array[i]=''D'';
     pEdit->SetWindowText(g_Array);
  Sleep(1000);
 }
 critical_section.Unlock();
 return 0;
}
分别双击按钮IDC_WRITEW和IDC_WRITED,添加其响应函数:
void CMultiThread8Dlg::OnWritew() 
{
 CWinThread *pWriteW=AfxBeginThread(WriteW,
  &m_ctrlW,
  THREAD_PRIORITY_NORMAL,
  0,
  CREATE_SUSPENDED);
 pWriteW->ResumeThread();
}
void CMultiThread8Dlg::OnWrited() 
{
 CWinThread *pWriteD=AfxBeginThread(WriteD,
  &m_ctrlD,
  THREAD_PRIORITY_NORMAL,
  0,
  CREATE_SUSPENDED);
 pWriteD->ResumeThread();
 
}


本文来自电脑杂谈,转载请注明本文网址:
快3网上购买http://www.kadakong.com/a/jisuanjixue/article-121556-1.html

相关阅读
发表评论  请自觉遵守互联网相关的政策法规,严禁发布、暴力、反动的言论

湖北快3开奖 快3网上购买 恒彩彩票投注 足彩单场网上投注 冠军彩票投注 快赢彩票官网 恒彩彩票开户 万发彩票登陆 万发彩票平台 快3投注网