VC++多线程,互斥对象,事件对象,关键代码段实现线程同步

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


/*#include "stdafx.h"
#include<iostream>
using namespace std;
#include<Windows.h>
DWORD WINAPI Fun1Proc(LPVOID lpParameter);//thread data
DWORD WINAPI Fun2Proc(LPVOID lpParameter);//thread data
 
int index=0;
int tickets=10;
HANDLE hMutex;
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);
 
    //创建互斥对象
    hMutex=CreateMutex(NULL,TRUE,_T("tickets"));
    if (hMutex)
    {
        if (ERROR_ALREADY_EXISTS==GetLastError())
        {
            cout<<"only one instance can run!"<<endl;
            return 0;
        }
    }
    WaitForSingleObject(hMutex,INFINITE);
    ReleaseMutex(hMutex);
    ReleaseMutex(hMutex);
     system("pause");
    //Sleep(4000);
}
//线程1的入口函数
DWORD WINAPI Fun1Proc(LPVOID lpParameter)//thread data
{
    while (true)
    {
        ReleaseMutex(hMutex);
        WaitForSingleObject(hMutex,INFINITE);
        if (tickets>0)
        {
            Sleep(1);
            cout<<"thread1 sell ticket :"<<tickets--<<endl;
        }
        else
            break;
        ReleaseMutex(hMutex);
    }
 
    return 0;
}
//线程2的入口函数
DWORD WINAPI Fun2Proc(LPVOID lpParameter)//thread data
{
    while (true)
    {
        ReleaseMutex(hMutex);
        WaitForSingleObject(hMutex,INFINITE);
        if (tickets>0)
        {
            Sleep(1);
            cout<<"thread2 sell ticket :"<<tickets--<<endl;
        }
        else
            break;
        ReleaseMutex(hMutex);
    }
     
    return 0;
}*/
/*#include "stdafx.h"
#include <windows.h>    //基于事件对象
#include<iostream>     //可见事件对象可分为两种,一种是人工重置的,另一种是自动重置的。当人工重置的事件得到通知时,等待该时间的所有线程均变为可调度线程。而当一个自动事件得到通知时,等待该时间的所有线程中只有一个线程变为可调度线程。
using namespace std;
DWORD WINAPI Fun1Proc(LPVOID lpParameter);//thread data
DWORD WINAPI Fun2Proc(LPVOID lpParameter);//thread data
 
int tickets=100;
HANDLE g_hEvent;
int _tmain(int argc, _TCHAR* argv[])
{
    HANDLE hThread1;
    HANDLE hThread2;
    //创建人工重置事件内核对象
    g_hEvent=CreateEvent(NULL,FALSE,TRUE,_T("tickets"));//g_hEvent=CreateEvent(NULL,TRUE,FALSE,"tickets");等待该时间的所有线程均变为可调度线程。
    if (g_hEvent)                                    //若为TRUE则初始化创建的事件对象为有信号的(signaled),否则将创建的事件对象初始化为无信号的(nonsignaled)。
    {
        if (ERROR_ALREADY_EXISTS==GetLastError())
        {
            cout<<"only one instance can run!"<<endl;
            return 0;
        }
    }
    SetEvent(g_hEvent);
 
    //创建线程
    hThread1=CreateThread(NULL,0,Fun1Proc,NULL,0,NULL);
    hThread2=CreateThread(NULL,0,Fun2Proc,NULL,0,NULL);
    CloseHandle(hThread1);
    CloseHandle(hThread2);
     
    //让主线程睡眠4秒
      system("pause");
    //Sleep(4000);
    //关闭事件对象句柄
    CloseHandle(g_hEvent);
}
//线程1的入口函数
DWORD WINAPI Fun1Proc(LPVOID lpParameter)//thread data
{
    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;
}
//线程2的入口函数
DWORD WINAPI Fun2Proc(LPVOID lpParameter)//thread data
{
    while (true)
    {
SetEvent(g_hEvent);
        //请求事件对象
        WaitForSingleObject(g_hEvent,INFINITE);
        //ResetEvent(g_hEvent);
        if (tickets>0)
        {
            Sleep(1);
            cout<<"thread2 sell ticket :"<<tickets--<<endl;
            SetEvent(g_hEvent);
        }
        else
        {
            SetEvent(g_hEvent);
            break;
        }
    }
 
    return 0;
}*/
//利用关键代码段实现多线程同步不好,容易出错,运行失败。须调试。
#include "stdafx.h"
#include <iostream>
#include <windows.h>
using namespace std;


// 声明两个线程函数
DWORD WINAPI ThreadProc1(
       LPVOID lpParameter   // thread data
       );


DWORD WINAPI ThreadProc2(
       LPVOID lpParameter   // thread data
       );


// 全局票数
int gTicket = 100;


// 关键代码段
CRITICAL_SECTION gSection;




int _tmain(int argc, _TCHAR* argv[])
{
HANDLE hThread1;
HANDLE hThread2;
 // 初始化关键代码段,必须先于线程的创建
 InitializeCriticalSection(&gSection);


 // 创建两个线程句柄
  hThread1 = CreateThread(NULL, 0, ThreadProc1, NULL, 0, NULL);
  hThread2 = CreateThread(NULL, 0, ThreadProc2, NULL, 0, NULL);
  //InitializeCriticalSection(&gSection);
 // 关闭两个线程句柄
 CloseHandle(hThread1);
 CloseHandle(hThread2);


 // 主线程sleep 4秒,使别的线程获取权利。
 Sleep(4000);
 
 // 删除关键代码段
 DeleteCriticalSection(&gSection);


 system("pause");
 return 0;
}


// 定义两个线程函数
DWORD WINAPI ThreadProc1(LPVOID lpParameter )
{
 while(true)
 {
  EnterCriticalSection(&gSection);       // 进入关键代码段
  if(gTicket > 0)
  {
 Sleep(1);
   cout<<"thread1 sell ticket "<<gTicket--<<endl;
  }
  else
  {
   break;
   LeaveCriticalSection(&gSection);
  }
 // LeaveCriticalSection(&gSection);       // 离开关键代码段
 }
 return 0;
}


DWORD WINAPI ThreadProc2(LPVOID lpParameter )
{
 while(true)
 {
  EnterCriticalSection(&gSection);       // 进入关键代码段
  if(gTicket > 0)
  {
 Sleep(1);
   cout<<"thread2 sell ticket "<<gTicket--<<endl;
  }
  else
  {
   break;
   LeaveCriticalSection(&gSection);
  }
 // LeaveCriticalSection(&gSection);       // 离开关键代码段
 }
 return 0;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值