现在的位置: 首页 > 综合 > 正文

windows多线程(sunxin vc++ 笔记2)

2013年02月23日 ⁄ 综合 ⁄ 共 4412字 ⁄ 字号 评论关闭

多线程
例1 多线程的创建
#include <windows.h>
#include <iostream.h>
DWORD WINAPI Fun1Proc(
  LPVOID lpParameter  //thread data
);
int index=0;
void main()
{
  HANDLE hthread1;
  hThread1=CreateThread(NULL,0,Fun1Proc,NULL,0,NULL);
  CloseHandle(hThread1); //在主线程关闭这个线程的句柄,递减这个线程内核对象的使用计数
  while(index++<1000)
     cout<<"main thread is running"<<endl; 
//  Sleep(10);

/*使主线程暂停运行10ms,防止因主线程退出导致进程结束而回收进程资源,使线程也结束(这里windows线程相当于java里的守护线程,一旦main主线程退出,其它线程就结束) */
}

DWORD WINAPI Fun1Proc(
    LPVOID lpParameter  //thread data
)
{  
    while(index++<1000)
        cout<<"thread1 is running"<<endl;//在单CPU下,主线程与thread1交替运行
    return 0;
}

------------------------------
例2 模拟火车站售票系统(互斥对象的讲解;采用互斥对象来实现多线程的同步)
#include <windows.h>
#include <iostream.h>
DWORD WINAPI Fun1Proc(
  LPVOID lpParameter  //thread data
);
DWORD WINAPI Fun2Proc(
  LPVOID lpParameter  //thread data
);
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); //在主线程关闭这个线程的句柄,递减这个线程内核对象的使用计数
  /*while(index++<1000)
     cout<<"main thread is running"<<endl; */
  hMutex=CreateMutex(NULL,FALSE,NULL);//创建一个匿名互斥对象
/* 注:若将这里改为hMutex=CreateMutex(NULL,TRUE,NULL)主线程main将拥有互斥对象,使互斥对象的计数器增为1(对应 拥有的ID为主线程ID),但主线程并没有释放,所以Thread1和Thread2将一直等待不能行,知道主线程Sleep(4000)结束,进程退出 (同时,由于在主线程中创建互斥对象的时候,操作系统同时会将主线程的ID号赋给互斥对象hMutex的ID,于是在Thread1和Thread2中想 在WaitForSingleObject之前使用ReleaseMutex也是无用的,因为操作系统会先判断当前线程ID和互斥对象的ID是否相等,所 以不能释放互斥对象,所以加入下面一句:ReleasehMutex(hMutex)。若在这ReleasehMutex前又 WaitForSingleObject(hMutex,INFINITE),那么因为ID一样,所以WaitForSingleObject可以使计数 器又增1变为2,所以要ReleaseMutex两次才能变为0,所以要再加一句ReleasehMutex(hMutex))。总之,对每个线程,请求 拥有多少次互斥对象,就要释放多少次。*/
  Sleep(4000);
}

DWORD WINAPI Fun1Proc(
    LPVOID lpParameter  //thread data
)
{  
    /*while(index++<1000)
        cout<<"thread1 is running"<<endl;//在单CPU下,主线程与thread1交替运行*/
    while(TRUE)
    {
         //ReleaseMutex(hMutex);
         //无限等待,直到所等待的互斥信号hMutex变为有信号状态才继续往下运行
         WaitForSingleObject(hMutex,INFINITE);
         if(tickets>0)
               cout<<"thread1 sell ticket:"<<tickets--<<endl;
         else
            break;
         ReleaseMutex(hMutex);//释放互斥对象
    }
    return 0;
}
DWORD WINAPI Fun2Proc(
    LPVOID lpParameter  //thread data
)
{  
    while(TRUE)
    {
         //ReleaseMutex(hMutex);
         WaitForSingleObject(hMutex,INFINITE);
         if(tickets>0)
               cout<<"thread2 sell ticket:"<<tickets--<<endl;
         else
            break;
         ReleaseMutex(hMutex);//释放互斥对象
    }
    return 0;
}

-------------------------------
例3 操作系统维护了线程及其相关的互斥对象的信息
#include <windows.h>
#include <iostream.h>
DWORD WINAPI Fun1Proc(
  LPVOID lpParameter  //thread data
);
DWORD WINAPI Fun2Proc(
  LPVOID lpParameter  //thread data
);
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); //在主线程关闭这个线程的句柄,递减这个线程内核对象的使用计数

  hMutex=CreateMutex(NULL,FALSE,NULL);//创建一个匿名互斥对象

  Sleep(4000);
}

DWORD WINAPI Fun1Proc(
    LPVOID lpParameter  //thread data
)
{  
    WaitForSingleObject(hMutex,INFINITE);
    cout<<"thread1 is running"<<endl;
/* 这里Thread1没有调用ReleaseMutex去释放互斥对象,但还是可以运行Thread2,因为,当Thread1不是while循环的,当 Thread1执行完毕,操作系统会自动回收Thread1线程拥有的互斥对象,使hMutex的ID和计数器都归为0,因为操作系统维护了线程及其相关 的互斥对象的信息。但hMutex保护的代码将不可知,程序将是不安全的。*/ 
    return 0;
}
DWORD WINAPI Fun2Proc(
    LPVOID lpParameter  //thread data
)
{  
    WsitforSingleObject(hMutex,INFINITE);  
    cout<<"thread2 is running"<<endl;
    return 0;
}

----------------------------
例4 利用命名互斥对象保证应用程序只有一个实例运行
#include <windows.h>
#include <iostream.h>
DWORD WINAPI Fun1Proc(
  LPVOID lpParameter  //thread data
);
DWORD WINAPI Fun2Proc(
  LPVOID lpParameter  //thread data
);
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); //在主线程关闭这个线程的句柄,递减这个线程内核对象的使用计数

  hMutex=CreateMutex(NULL,TRUE,"tickets");
  if(hMutex)
  {
    if(ERROR_ALREADY_EXISTS==GetLastError())
     {
          cout<<"only instance can run!"<<endl;
          return;
/*利用创建互斥对象hMutex的返回值,可以保证应用程序只能运行一个实例,比如平常用的“金山词霸”就只能跑一个实例。*/
     }
  }
  Sleep(4000);
}

DWORD WINAPI Fun1Proc(
    LPVOID lpParameter  //thread data
)
{  
    WaitForSingleObject(hMutex,INFINITE);
    cout<<"thread1 is running"<<endl;
    return 0;
}
DWORD WINAPI Fun2Proc(
    LPVOID lpParameter  //thread data
)
{  
    WsitforSingleObject(hMutex,INFINITE);  
    cout<<"thread2 is running"<<endl;
    return 0;

抱歉!评论已关闭.