临界区的使用

转自:http://blog.sina.com.cn/s/blog_43eb83b90100gb4a.html

1.CriticalSection


CriticalSection是在控制台程序等非MFC程序中可直接使用的临界区。

基本手法是这样的:

CRITICAL_SECTIONg_cs;                定义一个临界区对象
InitializeCriticalSection( &g_cs);   初始化该对象
EnterCriticalSection( &g_cs);        需要锁定的时候进入临界区
.......
LeaveCriticalSection( &g_cs);        需要解开限制离开临界区时
........   
DeleteCriticalSection( &g_cs);       一切都搞定后,销毁掉该对象


程序例子如下:

// thread.cpp : 定义控制台应用程序的入口点。
//


#include "stdafx.h"
#include <windows.h>
#include <iostream>
using namespace std;

int index=0;
int tickets=10;

CRITICAL_SECTION g_cs;


DWORD  WINAPI Fun1Proc( LPVOID lpParameter );
DWORD  WINAPI Fun2Proc( LPVOID lpParameter ) ;

int _tmain(int argc, _TCHAR* argv[])
{
InitializeCriticalSection( &g_cs );
HANDLE hThread1;
HANDLE hThread2;
hThread1=CreateThread(NULL,0,Fun1Proc,NULL,0,NULL);
   hThread2=CreateThread(NULL,0,Fun2Proc,NULL,0,NULL);
CloseHandle(hThread1);
CloseHandle(hThread2);
while(tickets>0)
{
EnterCriticalSection( &g_cs );
cout < <"main thread is running"< <endl;
LeaveCriticalSection( &g_cs );
Sleep(10);
}
DeleteCriticalSection( &g_cs );
return 0;
}

DWORD  WINAPI Fun1Proc( LPVOID lpParameter)
{
while(TRUE)
{
if(tickets>0)
{
EnterCriticalSection( &g_cs );
cout < <"thread1 sell ticket:"< <tickets-- <<endl;
LeaveCriticalSection( &g_cs );
}
else
break;
}
return 0;
}


DWORD  WINAPI Fun2Proc( LPVOID lpParameter )
{
while(TRUE)
{
if(tickets>0)
{
EnterCriticalSection( &g_cs );
cout < <"thread2 sell ticket:"< <tickets-- <<endl;
LeaveCriticalSection( &g_cs );
}
else
break;
}
return 0;

 


2. CCriticalSection 是专门用在MFC程序里已经封装好的临界区类

Lock()后代码用到的资源自动被视为临界区内的资源被保护。UnLock后别的线程才能访问这些资源。

比较CriticalSection,CCriticalSection不用initialize,使用也很方便。


 //CriticalSection
  CCriticalSection global_CriticalSection;
 
  // 共享资源
  char global_Array[256];
 
  //初始化共享资源
  void InitializeArray()
  {
   for(int i =0;i<256;i++)
   {
   global_Array[i]=I;
   }
  }
 
  //写线程
  UINT Global_ThreadWrite(LPVOID pParam)
  {
   CEdit *ptr=(CEdit*)pParam;
  ptr->SetWindowText("");
   //进入临界区
  global_CriticalSection.Lock();
   for(int i =0;i<256;i++)
   {
   global_Array[i]=W;
  ptr->SetWindowText(global_Array);
   Sleep(10);
   }

//离开临界区
  global_CriticalSection.Unlock();
   return 0;
  }
 
  //删除线程
  UINT Global_ThreadDelete(LPVOID pParam)
  {
   CEdit *ptr=(CEdit*)pParam;
  ptr->SetWindowText("");
   //进入临界区
  global_CriticalSection.Lock();
   for(int i =0;i<256;i++)
   {
   global_Array[i]=D;
  ptr->SetWindowText(global_Array);
   Sleep(10);
   }
 
//离开临界区
  global_CriticalSection.Unlock();
   return 0;
  }

 

 


下面举例说明临界区的伟大作用


.h

#include <iostream>
using namespace std;
#include <tchar.h>
#include <windows.h>


// ThreadTicket.cpp : 定义控制台应用程序的入口点。
//

#include "stdafx.h"

 


int index=0;
int tickets=10;

int _tmain(int argc, _TCHAR* argv[])
{
 HANDLE hThread1;
 HANDLE hThread2;
 hThread1=CreateThread(NULL,0,Fun1Proc,NULL,0,NULL);
   hThread2=CreateThread(NULL,0,Fun2Proc,NULL,0,NULL);
 CloseHandle(hThread1);
 CloseHandle(hThread2);
 while(tickets>0)
  cout<<"mainthread is running"<<endl;
 Sleep(10);
 return 0;
}

DWORD WINAPI Fun1Proc(
 LPVOID lpParameter
)
{
 while(TRUE)
 {
  if(tickets>0)
  {
   cout<<"thread1sellticket:"<<tickets--<<endl;
   
  }
  else
   break;
 }
 return 0;
}


DWORD WINAPI Fun2Proc(
 LPVOID lpParameter
)
{
 while(TRUE)
 {
  if(tickets>0)
  {
   cout<<"thread2sellticket:"<<tickets--<<endl;
   
  }
  else
   break;
 }
 return 0;
}


这种两线程交替售票问题,加上主线程输出那句,共3句话交替输出。

可输出时常出现

maithread1 sell ticthread2 sell ticn thread isrunninket:10
thread1 selket:9
thread2 sellg
main thread is rl ticket:8
thread1 ticket:7
thread2 unning
main thread sell ticket:6
thrsell ticket:5
thre is running
main tead1 sell ticket:4ad2 sell ticket:3
hread is running
m
thread1 sell tickthread2 sell tickeain thread is runnet:2
t:1
ing
Press any key to continue

文字输出不完整就跳到下一个线程的情况。需要用临界区


#include "stdafx.h"
#include <windows.h>
#include <iostream>
using namespace std;

int index=0;
int tickets=10;

CRITICAL_SECTION g_cs;


DWORD  WINAPI Fun1Proc( LPVOID lpParameter );
DWORD  WINAPI Fun2Proc( LPVOID lpParameter ) ;

int _tmain(int argc, _TCHAR* argv[])
{
InitializeCriticalSection( &g_cs );
HANDLE hThread1;
HANDLE hThread2;
hThread1=CreateThread(NULL,0,Fun1Proc,NULL,0,NULL);
   hThread2=CreateThread(NULL,0,Fun2Proc,NULL,0,NULL);
CloseHandle(hThread1);
CloseHandle(hThread2);
while(tickets>0)
{
EnterCriticalSection( &g_cs );
cout < <"main thread is running"< <endl;
LeaveCriticalSection( &g_cs );
Sleep(10);
}
DeleteCriticalSection( &g_cs );
return 0;
}

DWORD  WINAPI Fun1Proc( LPVOID lpParameter)
{
while(TRUE)
{
if(tickets>0)
{
EnterCriticalSection( &g_cs );
cout < <"thread1 sell ticket:"< <tickets-- <<endl;
LeaveCriticalSection( &g_cs );
}
else
break;
}
return 0;
}


DWORD 

WINAPI Fun2Proc( LPVOID lpParameter )
{
while(TRUE)
{
if(tickets>0)
{
EnterCriticalSection( &g_cs );
cout < <"thread2 sell ticket:"< <tickets-- <<endl;
LeaveCriticalSection( &g_cs );
}
else
break;
}
return 0;
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值