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

指南针的天空

你永远也看不到我最寂寞时候的样子,因为只有你不在我身边的时候,我才最寂寞。

 
 
 

日志

 
 

VC下线程同步的三种方法(互斥、事件、临界区)   

2008-04-02 22:23:24|  分类: Visual C++ |  标签: |举报 |字号 订阅

  下载LOFTER 我的照片书  |

编写环境 VS.NET VC++ 控制台编程

学习目的:掌握线程同步的基本使用方法.

转载: http://www.cnweblog.com/chefZ/archive/2007/08/19/247609.html


首选使用临界区对象,主要原因是使用简单。

#include <windows.h>

#include <iostream>

using namespace std;

DWORD WINAPI Fun1Proc(LPVOID lpParameter);

DWORD WINAPI Fun2Proc(LPVOID lpParameter);

int tickets=100;

CRITICAL_SECTION g_csA;

CRITICAL_SECTION g_csB;

void main()

{

 HANDLE hThread1;

 HANDLE hThread2;

 hThread1=CreateThread(NULL,0,Fun1Proc,NULL,0,NULL);

 hThread2=CreateThread(NULL,0,Fun2Proc,NULL,0,NULL);

 CloseHandle(hThread1);

 CloseHandle(hThread2);

 InitializeCriticalSection(&g_csA);

 InitializeCriticalSection(&g_csB);

 Sleep(40000);

 DeleteCriticalSection(&g_csA);

 DeleteCriticalSection(&g_csB);

}

DWORD WINAPI Fun1Proc(LPVOID lpParameter)

{

 while (TRUE)

 {

  EnterCriticalSection(&g_csA);

  Sleep(1);

  //EnterCriticalSection(&g_csB);//临界区的同步和互锁

  if (tickets>0)

  {

   Sleep(1);

   cout<<"Thread1 sell ticket :"<<tickets--<<endl;

   //LeaveCriticalSection(&g_csB);

   LeaveCriticalSection(&g_csA);

  }

  else

  {

   //LeaveCriticalSection(&g_csB);

   LeaveCriticalSection(&g_csA);

   break;

  }

 }

 return 0;

}

DWORD WINAPI Fun2Proc(LPVOID lpParameter)

{

 while (TRUE)

 {

  EnterCriticalSection(&g_csB);

  Sleep(1);

  EnterCriticalSection(&g_csA);

  if (tickets>0)

  {

   Sleep(1);

   cout<<"Thread2 sell ticket :"<<tickets--<<endl;

   LeaveCriticalSection(&g_csA);

   LeaveCriticalSection(&g_csB);

  }

  else

  {

   LeaveCriticalSection(&g_csA);

   LeaveCriticalSection(&g_csB);

   break;

  }

 }

 return 0;

}


二、使用互斥对象

#include <windows.h>

#include <iostream>

using namespace std;

DWORD WINAPI Fun1Proc(LPVOID lpParameter);

DWORD WINAPI Fun2Proc(LPVOID lpParameter);

int index =0;

int tickets=100;

HANDLE hMutex;

void main()

{

 HANDLE hThread1;

 HANDLE hThread2;

 //创建线程

 hThread1=CreateThread(NULL,0,Fun1Proc,NULL,0,NULL);

 hThread2=CreateThread(NULL,0,Fun2Proc,NULL,0,NULL);

 CloseHandle(hThread1);

 CloseHandle(hThread2);

 //**************************************************************

 //保证应用程序只有一个实例运行,创建一个命名的互斥对象.

 hMutex=CreateMutex(NULL,TRUE,LPCTSTR("tickets"));

 //创建时主线程拥有该互斥对象,互斥对象的线程ID为主线程的ID,同时将该互斥对象内部计数器置为1

 if (hMutex)

 {

  if (ERROR_ALREADY_EXISTS==GetLastError())

  {

   cout<<"only one instance can run!"<<endl;

   //Sleep(40000);

   return;

  }

 }

 //**************************************************************

 WaitForSingleObject(hMutex,INFINITE);

 //使用该函数请求互斥对象时,虽说该对象处于无信号状态,但因为请求的线程ID和该互斥对象所有者的线程ID是相同的.

 //所以仍然可以请求到这个互斥对象,于是该互斥对象内部计数器加1,内部计数器的值为2.

 ReleaseMutex(hMutex);//释放一次互斥对象,该互斥对象内部计数器的值递减1,操作系统不会将这个互斥对象变为已通知状态.

 ReleaseMutex(hMutex);//释放一次互斥对象,该互斥对象内部计数器的值为0,同时将该对象设置为已通知状态.

 //对于互斥对象来说,谁拥有谁释放

 Sleep(40000);

}

DWORD WINAPI Fun1Proc(LPVOID lpParameter)

{

 while (TRUE)

 {

  WaitForSingleObject(hMutex,INFINITE);//等待互斥对象有信号

  if (tickets>0)

  {

   Sleep(1);

   cout<<"thread1 sell ticket :"<<tickets--<<endl;

  }

  else

   break;

  ReleaseMutex(hMutex);//设置该互斥对象的线程ID为0,并且将该对象设置为有信号状态

 }

 return 0;

}

DWORD WINAPI Fun2Proc(LPVOID lpParameter)

{

 while (TRUE)

 {

  WaitForSingleObject(hMutex,INFINITE);

  if (tickets>0)

  {

   Sleep(1);

   cout<<"thread2 sell ticket :"<<tickets--<<endl;

  }

  else

   break;

  ReleaseMutex(hMutex);

 }

 return 0;

}


三、使用事件对象

#include <windows.h>
#include <iostream>
using namespace std;
DWORD WINAPI Fun1Proc(LPVOID lpParameter);
DWORD WINAPI Fun2Proc(LPVOID lpParameter);
int tickets=100;
HANDLE g_hEvent;

void main()
{
 HANDLE hThread1;
 HANDLE hThread2;
 //**************************************************
 //创建一个命名的自动重置事件内核对象
 g_hEvent=CreateEvent(NULL,FALSE,FALSE,LPCTSTR("tickets"));
 if (g_hEvent)
 {
  if (ERROR_ALREADY_EXISTS==GetLastError())
  {
   cout<<"only one instance can run!"<<endl;
   return;
  }
 }
 //**************************************************
 SetEvent(g_hEvent);
 //创建线程
 hThread1=CreateThread(NULL,0,Fun1Proc,NULL,0,NULL);
 hThread2=CreateThread(NULL,0,Fun2Proc,NULL,0,NULL);

 Sleep(40000);
 //关闭事件对象句柄
 CloseHandle(g_hEvent);
}

DWORD WINAPI Fun1Proc(LPVOID lpParameter)
{
 while (TRUE)
 {
  WaitForSingleObject(g_hEvent,INFINITE);
  //ResetEvent(g_hEvent);
  if (tickets>0)
  {
   Sleep(1);
   cout<<"thread1 sell ticket :"<<tickets--<<endl;
   SetEvent(g_hEvent);
  }
  else
  {
   SetEvent(g_hEvent);
   break;
  }
 }
 return 0;
}

DWORD WINAPI Fun2Proc(LPVOID lpParameter)
{
 while (TRUE)
 {
  WaitForSingleObject(g_hEvent,INFINITE);
  //ResetEvent(g_hEvent);
  if (tickets>0)
  {
   cout<<"Thread2 sell ticket :"<<tickets--<<endl;
   SetEvent(g_hEvent);
  }
  else
  {
   SetEvent(g_hEvent);
   break;
  }
 }
 return 0;
}

  评论这张
 
阅读(119)| 评论(0)
推荐 转载

历史上的今天

评论

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

页脚

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