Arce 发表于 2021-7-20 21:41:44

c++多线程例(互斥体,共同访问)

view plain copy
print?
<pre name="code" class="cpp">//这是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=10;
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,"tickets");
    if (hMutex)
    {
      if (ERROR_ALREADY_EXISTS==GetLastError())//得到错误:已经存在
      {
      // 如果已有互斥量存在则释放句柄并复位互斥量
       CloseHandle(m_hMutex);
       m_hMutex = NULL;
            cout<<"only one instance can run!"<<endl;
            return;
      }
    }
    WaitForSingleObject(hMutex,INFINITE);
    ReleaseMutex(hMutex);//申请了两次就要施放两次(没搞懂在哪里申请了两次?难道建立一次,wait也算一次?)
    ReleaseMutex(hMutex);//谁申请谁施放
      
    Sleep(4000);//让主线程睡4秒,让其他线程有时间执行完他们的代码,如果不睡就会出现其他线程执行不完或出错的情况,但时如果不知道线程需要多少时间执行,那应该写多少时间?
}
//线程1的入口函数
DWORD WINAPI Fun1Proc(LPVOID lpParameter)//thread data
{
    while (true)//无限循环线程
    {
      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)
    {
      WaitForSingleObject(hMutex,INFINITE);
      if (tickets>0)
      {
            Sleep(1);
            cout<<"thread2 sell ticket :"<<tickets--<<endl;
      }
      else
            break;
      ReleaseMutex(hMutex);
    }
      
    return 0;
}
//详解
HANDLE CreateMutex(
LPSECURITY_ATTRIBUTES lpMutexAttributes, // 指向安全属性的指针
BOOL bInitialOwner, // 初始化互斥对象的所有者
LPCTSTR lpName // 指向互斥对象名的指针
);
参数   
lpMutexAttributes   
指向一个SECURITY_ATTRIBUTES结构的指针,这个结构决定互斥体句柄是否被子进程继承。      
bInitialOwner   
布尔类型,决定互斥体的创建者是否为拥有者   
lpName   
指向互斥体名字字符串的指针。互斥体可以有名字。   
互斥体的好处是可以在进程间共享</pre><br>
<br>
<pre></pre>
<pre name="code" class="cpp"></pre><pre name="code" class="cpp"></pre>
<pre></pre>
<pre></pre>
<pre></pre> view plain copy
print?
//这是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=10;
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,"tickets");
    if (hMutex)
    {
      if (ERROR_ALREADY_EXISTS==GetLastError())//得到错误:已经存在
      {
      // 如果已有互斥量存在则释放句柄并复位互斥量
       CloseHandle(m_hMutex);
       m_hMutex = NULL;
            cout<<"only one instance can run!"<<endl;
            return;
      }
    }
    WaitForSingleObject(hMutex,INFINITE);
    ReleaseMutex(hMutex);//申请了两次就要施放两次(没搞懂在哪里申请了两次?难道建立一次,wait也算一次?)
    ReleaseMutex(hMutex);//谁申请谁施放
      
    Sleep(4000);//让主线程睡4秒,让其他线程有时间执行完他们的代码,如果不睡就会出现其他线程执行不完或出错的情况,但时如果不知道线程需要多少时间执行,那应该写多少时间?
}
//线程1的入口函数
DWORD WINAPI Fun1Proc(LPVOID lpParameter)//thread data
{
    while (true)//无限循环线程
    {
      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)
    {
      WaitForSingleObject(hMutex,INFINITE);
      if (tickets>0)
      {
            Sleep(1);
            cout<<"thread2 sell ticket :"<<tickets--<<endl;
      }
      else
            break;
      ReleaseMutex(hMutex);
    }
      
    return 0;
}
//详解
HANDLE CreateMutex(
LPSECURITY_ATTRIBUTES lpMutexAttributes, // 指向安全属性的指针
BOOL bInitialOwner, // 初始化互斥对象的所有者
LPCTSTR lpName // 指向互斥对象名的指针
);
参数   
lpMutexAttributes   
指向一个SECURITY_ATTRIBUTES结构的指针,这个结构决定互斥体句柄是否被子进程继承。      
bInitialOwner   
布尔类型,决定互斥体的创建者是否为拥有者   
lpName   
指向互斥体名字字符串的指针。互斥体可以有名字。   
互斥体的好处是可以在进程间共享
view plain copy
print?
//这是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=10;
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,"tickets");
    if (hMutex)
    {
      if (ERROR_ALREADY_EXISTS==GetLastError())//得到错误:已经存在
      {
      // 如果已有互斥量存在则释放句柄并复位互斥量
       CloseHandle(m_hMutex);
       m_hMutex = NULL;
            cout<<"only one instance can run!"<<endl;
            return;
      }
    }
    WaitForSingleObject(hMutex,INFINITE);
    ReleaseMutex(hMutex);//申请了两次就要施放两次(没搞懂在哪里申请了两次?难道建立一次,wait也算一次?)
    ReleaseMutex(hMutex);//谁申请谁施放
      
    Sleep(4000);//让主线程睡4秒,让其他线程有时间执行完他们的代码,如果不睡就会出现其他线程执行不完或出错的情况,但时如果不知道线程需要多少时间执行,那应该写多少时间?
}
//线程1的入口函数
DWORD WINAPI Fun1Proc(LPVOID lpParameter)//thread data
{
    while (true)//无限循环线程
    {
      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)
    {
      WaitForSingleObject(hMutex,INFINITE);
      if (tickets>0)
      {
            Sleep(1);
            cout<<"thread2 sell ticket :"<<tickets--<<endl;
      }
      else
            break;
      ReleaseMutex(hMutex);
    }
      
    return 0;
}
//详解
HANDLE CreateMutex(
LPSECURITY_ATTRIBUTES lpMutexAttributes, // 指向安全属性的指针
BOOL bInitialOwner, // 初始化互斥对象的所有者
LPCTSTR lpName // 指向互斥对象名的指针
);
参数   
lpMutexAttributes   
指向一个SECURITY_ATTRIBUTES结构的指针,这个结构决定互斥体句柄是否被子进程继承。      
bInitialOwner   
布尔类型,决定互斥体的创建者是否为拥有者   
lpName   
指向互斥体名字字符串的指针。互斥体可以有名字。   
互斥体的好处是可以在进程间共享

//这是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=10;
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,"tickets");
    if (hMutex)
    {
      if (ERROR_ALREADY_EXISTS==GetLastError())//得到错误:已经存在
      {
// 如果已有互斥量存在则释放句柄并复位互斥量
CloseHandle(m_hMutex);
m_hMutex = NULL;
            cout<<"only one instance can run!"<<endl;
            return;
      }
    }
    WaitForSingleObject(hMutex,INFINITE);
    ReleaseMutex(hMutex);//申请了两次就要施放两次(没搞懂在哪里申请了两次?难道建立一次,wait也算一次?)
    ReleaseMutex(hMutex);//谁申请谁施放
   
    Sleep(4000);//让主线程睡4秒,让其他线程有时间执行完他们的代码,如果不睡就会出现其他线程执行不完或出错的情况,但时如果不知道线程需要多少时间执行,那应该写多少时间?
}
//线程1的入口函数
DWORD WINAPI Fun1Proc(LPVOID lpParameter)//thread data
{
    while (true)//无限循环线程
    {
      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)
    {
      WaitForSingleObject(hMutex,INFINITE);
      if (tickets>0)
      {
            Sleep(1);
            cout<<"thread2 sell ticket :"<<tickets--<<endl;
      }
      else
            break;
      ReleaseMutex(hMutex);
    }
   
    return 0;
}
//详解
HANDLE CreateMutex(
LPSECURITY_ATTRIBUTES lpMutexAttributes, // 指向安全属性的指针
BOOL bInitialOwner, // 初始化互斥对象的所有者
LPCTSTR lpName // 指向互斥对象名的指针
);
参数
lpMutexAttributes
指向一个SECURITY_ATTRIBUTES结构的指针,这个结构决定互斥体句柄是否被子进程继承。   
bInitialOwner
布尔类型,决定互斥体的创建者是否为拥有者
lpName
指向互斥体名字字符串的指针。互斥体可以有名字。
互斥体的好处是可以在进程间共享
文档来源:51CTO技术博客https://blog.51cto.com/u_15308480/3144920
页: [1]
查看完整版本: c++多线程例(互斥体,共同访问)