VC多线程临界区

在使用多线程时,一般很少有多个线程完全独立的工作。往往是多个线程同时操作一个全局变量来获取程序的运行结果。多个线程同时访问同一个全局变量,如果都是读取操作,则不会出现问题。如果是写操作,则会发生错误。这时候,我们可以通过临界区,为全局变量设置一个保护,保证同时只有一个线程可以访问此变量,其他变量进入等待状态。

临界区(Critical Section)是一段独占对某些共享资源访问的代码,在任意时刻只允许一个线程对共享资源进行访问。如果有多个线程试图同时访问临界区,那么在有一个线程进入后其他所有试图访问此临界区的线程将被挂起,并一直持续到进入临界区的线程离开。临界区在被释放后,其他线程可以继续抢占,并以此达到用原子方式操作共享资源的目的。

临界区在使用时以CRITICAL_SECTION结构对象保护共享资源,并分别用 ①InitializeCriticalSection(&cs); //初始化临界区②EnterCriticalSection(&cs);//进入临界区③LeaveCriticalSection(&cs);//离开临界区④DeleteCriticalSection(&cs);//删除临界区

一般类程序(举例)

// 临界区结构对象

CRITICAL_SECTION g_cs;

// 共享资源

char g_cArray[10]

UINT ThreadProc1(LPVOID pParam)

{

 // 进入临界区

 EnterCriticalSection(&g_cs);

 // 对共享资源进行写入操作

 for (int i = 0; i < 10; i++)

 {

  g_cArray[i] = ’a’;

  Sleep(1);

 }

 // 离开临界区

 LeaveCriticalSection(&g_cs);

 return 0;

}

UINT ThreadProc2(LPVOID pParam)

{

 // 进入临界区

 EnterCriticalSection(&g_cs);

 // 对共享资源进行写入操作

 for (int i = 0; i < 10; i++)

 {

  g_cArray[10 - i - 1] = ’b’;

  Sleep(1);

 }

 // 离开临界区

 LeaveCriticalSection(&g_cs);

 return 0;

}

void CSampleView::OnCriticalSection()

{

 // 初始化临界区

 InitializeCriticalSection(&g_cs);

 // 启动线程

 AfxBeginThread(ThreadProc1, NULL);

 AfxBeginThread(ThreadProc2, NULL);

 // 等待计算完毕

 Sleep(300);

 // 报告计算结果

 CString sResult = CString(g_cArray);

 AfxMessageBox(sResult);

}

在使用临界区时,一般不允许其运行时间过长,只要进入临界区的线程还没有离开,其他所有试图进入此临界区的线程都会被挂起而进入到等待状态,并会在一定程度上影响。程序的运行性能。尤其需要注意的是不要将等待用户输入或是其他一些外界干预的操作包含到临界区。如果进入了临界区却一直没有释放,同样也会引起其他线程的长时间等待。换句话说,在执行了EnterCriticalSection()语句进入临界区后无论发生什么,必须确保与之匹配的LeaveCriticalSection()都能够被执行到。可以通过添加结构化异常处理代码来确保LeaveCriticalSection
()语句的执行。虽然临界区同步速度很快,但却只能用来同步本进程内的线程,而不可用来同步多个进程中的线程。

MFC为临界区提供有一个CCriticalSection类,使用该类进行线程同步处理是非常简单的,只需在线程函数中用CCriticalSection类成员函数 Lock()和UnLock()标定出被保护代码片段即可。对于上述代码,可通过CCriticalSection类将其改写如下:

MFC应用(举例)

// MFC临界区类对象

CCriticalSection g_cs;

// 共享资源

char g_cArray[10];

UINT ThreadProc1(LPVOID pParam)

{

 // 进入临界区

 g_cs.Lock();

 // 对共享资源进行写入操作

 for (int i = 0; i < 10; i++)

 {

  g_cArray[i] = ’a’;

  Sleep(1);

 }

 // 离开临界区

 g_cs.Unlock();

 return 0;

}

UINT ThreadProc2(LPVOID pParam)

{

 // 进入临界区

 g_cs.Lock();

 // 对共享资源进行写入操作

 for (int i = 0; i < 10; i++)

 {

  g_cArray[10 - i - 1] = ’b’;

  Sleep(1);

 }

 // 离开临界区

 g_cs.Unlock();

 return 0;

}

void CSampleView::OnCriticalSectionMfc()

{

 // 启动线程

 AfxBeginThread(ThreadProc1, NULL);

 AfxBeginThread(ThreadProc2, NULL);

 // 等待计算完毕

 Sleep(300);

 // 报告计算结果

 CString sResult = CString(g_cArray);

 AfxMessageBox(sResult);

}

VC多线程临界区,布布扣,bubuko.com

时间: 2024-10-10 13:22:27

VC多线程临界区的相关文章

VC多线程临界区(转)

用于理解CriticalSection. 在使用多线程时,一般很少有多个线程完全独立的工作.往往是多个线程同时操作一个全局变量来获取程序的运行结果.多个线程同时访问同一个全局变量,如果都是读取操作,则不会出现问题.如果是写操作,则会发生错误.这时候,我们可以通过临界区,为全局变量设置一个保护,保证同时只有一个线程可以访问此变量,其他变量进入等待状态.       临界区(Critical Section)是一段独占对某些共享资源访问的代码,在任意时刻只允许一个线程对共享资源进行访问.如果有多个线

VC++多线程编程-线程间的通信和线程同步

引用:http://blog.csdn.net/zjc0888/article/details/7372258 线程间通讯 一般而言,应用程序中的一个次要线程总是为主线程执行特定的任务,这样,主线程和次要线程间必定有一个信息传递的渠道,也就是主线程和次要线程间要进行通信.这种线程间的通信不但是难以避免的,而且在多线程编程中也是复杂和频繁的,下面将进行说明. 使用全局变量进行通信 由于属于同一个进程的各个线程共享操作系统分配该进程的资源,故解决线程间通信最简单的一种方法是使用全局变量.对于标准类型

VC++多线程编程

一.问题的提出 编写一个耗时的单线程程序: 新建一个基于对话框的应用程序SingleThread,在主对话框IDD_SINGLETHREAD_DIALOG添加一个按钮,ID为IDC_SLEEP_SIX_SECOND,标题为“延时6秒”,添加按钮的响应函数,代码如下: void CSingleThreadDlg::OnSleepSixSecond() { Sleep(6000); //延时6秒 } 编译并运行应用程序,单击“延时6秒”按钮,你就会发现在这6秒期间程序就象“死机”一样,不在响应其它消

VC多线程编程学习笔记(一)

最近两天在学多线程编程,有了一些心得,写下来和大家一起共勉.文中一些部分引用了韩耀旭的文章<多线程编程>http://www.vckbase.com/document/viewdoc/?id=1704和MSDN资料. 一.缘起 工作上要用到串口编程,本来一直是用mscomm控件来进行串口通讯的,后来觉得这个控件功能不灵活,想直接使用api编程,那就不可避免的要使用多线程技术:用一个支线程一直挂在那里监听串口,就不影响主线程的消息循环了. 二.为何要用多线程 有时候需要把程序的运行挂起一段时间,

VC++ 多线程编程,win32,MFC 例子(转)

一.问题的提出 编写一个耗时的单线程程序: 新建一个基于对话框的应用程序SingleThread,在主对话框IDD_SINGLETHREAD_DIALOG添加一个按钮,ID为IDC_SLEEP_SIX_SECOND,标题为“延时6秒”,添加按钮的响应函数,代码如下: void CSingleThreadDlg::OnSleepSixSecond() { Sleep(6000); //延时6秒 } 编译并运行应用程序,单击“延时6秒”按钮,你就会发现在这6秒期间程序就象“死机”一样,不在响应其它消

【转】VC 多线程中控制界面控件的几种方法

原文网址:https://software.intel.com/zh-cn/blogs/2010/11/30/vc-3 为了保证界面的用户体验经常要把数据处理等放到子线程中进行,然后把结果更新到主界面,通常有这样几种方法. 1. 启动线程时把控件关联变量的指针传参给线程函数,这种方法无疑是最简单的方法,但极容易造成访问异常,因为VC6中的控件都不是线程安全的. 2. 就是先进一点的方法,把控件的句柄传给线程函数,有时也不好用在子线程中通过SendNotifyMessage or PostMess

多线程-临界区

函数功能:初始化 函数原型: void InitializeCriticalSection(LPCRITICAL_SECTIONlpCriticalSection); 函数说明:定义关键段变量后必须先初始化. 函数功能:销毁 函数原型: void DeleteCriticalSection(LPCRITICAL_SECTIONlpCriticalSection); 函数说明:用完之后记得销毁. 函数功能:进入关键区域 函数原型: void EnterCriticalSection(LPCRITI

VC多线程的用法

.h 文件 #define WM_TEST    WM_USER + 1 class CTestThread : public CWinThread { DECLARE_DYNCREATE(CTestThread) protected: CTestThread (); virtual ~CTestThread (); public: virtual BOOL InitInstance(); virtual int  ExitInstance(); protected: afx_msg void

VC++多线程同步(一) Mutex互斥量

一 .同步机制的引入目的是为了解决三个主要问题 1为了控制线程之间共享资源的同步访问,保证共享资源的完整性.(比如一个线程正在更新一个数据,而另外一个线程正在读取该数据,那么就不知道该数据是新的还是旧的,为了避免这种状况的发生) 2确保线程之间的动作,以制定的次序发送,例如一个线程的触发,需要另外一个线程的结果,作为条件. 3为了控制某一个共享资源的最大访问量,例如我们同时只能处理5个客户的请求,这时候,我们需要放到队列进行等待. 二.同步概念就是等待 WIN32  提供了API 等待函数 DW