zoukankan      html  css  js  c++  java
  • c++下使用线程API函数版(基本概念以及同步)


       关于线程的基本概念,博友可参考我的c#Thread文章.本文所讨论的是在c++下使用线程.

       本文只是线程的一个浓缩版,目的是可以让大家能快速的熟悉在c++是使用线程,希望大家踊跃拍砖.

      用API函数CreateThread可创建线程.该函数原型为

      HANDLE CreateThread(
        LPSECURITY_ATTRIBUTES lpThreadAttributes,
        DWORN dwStackSize,
        LPTHREAD_START_ROUTINE lpStartAddress, 
        LPVOID lpParameter,
        DWORD dwCreationFlags, 
        LPDWORD lpThreadId
    )

    该函数参数较多,不过不用急,我们一步一步来分析参数.
    1:lpThreadAttributes 这个参数是指向SECURITY_ATTRIBUTES结构的指针.SECURITY_ATTRIBUTES结构主要主用是设置线程安全性的,我们在用

    CreateThread创建线程的时候可用NULL给它赋值(让创建的线程使用默认的安全性).

    2:dwStackSize  这个参数的主要是设置创建的线程栈的大小.这里出现了一个技术词(栈).
    栈是数据在内存中的一个位置。
    提到栈我们就顺便提下数据在内存中的存放形式。
    一般有如下形式
     栈:由编译器自动分配并且释放
     堆:一般由程序员手动释放.
     寄存器:一般存放全局变量和静态变量等
     
     对于int a这样的声明,自动自动为a在栈中开辟空间,而 person *p=new person这样的声明来说
    变量p就是存放在堆中,并且需要手动释放入delete p;在c#或java这样的语言来说回收由系统自动回收.
    一般我们不需要手动释放.
    在这里dwStackSize意义是设置线程dwStackSize的大小.如果这里设为0就默认使用和条用线程的函数一样大。

    3:lpStartAddress 指向LPTHREAD_START_ROUTINE类型的函数指针.是线程的起始地址


    4:pParameter 命令行参数 可为空

    5:dwCreationFlags 创建线程的附加标记.它可以是两个值中的一个可以是CREATE_SUSPENDED或者0,如果是CREATE_SUSPENDED,线程创建后处理

    暂停状态,为0则理解执行

    6:lpThreadId 这个参数是一个返回值,用来接收线程ID。。

    我们大致对CreateThread函数有所了解后,下面我们用一个简单的程序来说明下怎么使用线程


    我们用VC6创建一个空的控制台程序

    #include <windows.h>
    #include <iostream.h>

    //首先声明下线程函数地址
    DWORD WINAPI FunOne(
        LPVOID lpParameter
    );

    void main()
    {
        HANDLE hThread1;
        hThread1=CreateThread(NULL,0,FunOne,NULL,0,NULL);
        CloseHandle(hThread1);//关闭打开的线程句柄
        /*
        Sleep(1);
        这里如果不添加Sleep函数就会看见输出Response FunOne
        至于为什么请大家思考思考
        
    */
        cout<<"Response main"<<endl;
    }

    DWORD WINAPI FunOne(
        LPVOID lpParameter
    )
    {
        cout<<"Response FunOne "<<endl;
        return 0;
    };


    线程同步

       关于同步的概念在此我们也不讲解呢,由不太明白的博客可参考我的c#系列文章。在这里我将定义一个全局变量,用两个创建的线程来同事访

    问该变量.

       这里我们用到一个互斥对象mutex.
       我们可以用CreateMutex函数来创建互斥对象.互斥对象包含一个线程ID和一个计数器.ID标识当前线程的ID,计算器标明该线程使用互斥对象

    的次数.
    CreateMutex的函数原型入下
     HANDLE CreateMutex(
       LPSECURITY_ATTRIBUTES lpMutexAttributes,
       BOOL bInitialOwer,
       LPCTSTR lpName
    )


    1:lpMutexAttributes 安全性 和CreateThread第一个参数相同
    2:bInitialOwer BOOL类型 为true的话则创建者线程拥有使用互斥对象的拥有权,为false则不活的创建对象的所有权
    3:lpName 互斥对象的名称


    ReleaseMutex 释放互斥对象的拥有权.和WaitForSingleObject函数成对使WaitForSingleObject函数的功能是请求互斥对象的拥有权..

    下面是Demo

    #include <windows.h>
    #include <iostream.h>

    //首先声明下线程函数地址
    DWORD WINAPI FunOne(
        LPVOID lpParameter
    );

    DWORD WINAPI FunTwo(
        LPVOID lpParameter
    );


    int TxtNum=100;
    HANDLE hMutex;
    void main()
    {
        HANDLE hThread1;
        HANDLE hThread2;
        hThread1=CreateThread(NULL,0,FunOne,NULL,0,NULL);
        hThread2=CreateThread(NULL,0,FunTwo,NULL,0,NULL);
        CloseHandle(hThread1);//关闭打开的线程句柄
        CloseHandle(hThread2);
        hMutex=CreateMutex(NULL,FALSE,NULL);
        Sleep(5000);
    }
    DWORD WINAPI FunOne(
        LPVOID lpParameter
    )
    {
        for(int i=1;i<100;i++)
        {
            //INFINITE参数表示WaitForSingObject用该等待直到获得所有权
            WaitForSingleObject(hMutex,INFINITE);
            if(TxtNum>0)
            {
                cout<<"妈妈正在做第"<<TxtNum--<<"道菜"<<endl;
            }
            ReleaseMutex(hMutex);
        }
        return 0;
    }


    DWORD WINAPI FunTwo(
        LPVOID lpParameter
    )
    {
        for(int i=1;i<100;i++)
        {
            //INFINITE参数表示WaitForSingObject用该等待直到获得所有权
            WaitForSingleObject(hMutex,INFINITE);
            if(TxtNum>0)
            {
                cout<<"妈妈正在做第"<<TxtNum--<<"道菜"<<endl;
            }
            ReleaseMutex(hMutex);
        }
        return 0;
    }

    本片文章篇幅不长,欢迎交流
  • 相关阅读:
    springcloud 项目源码 微服务 分布式 Activiti6 工作流 vue.js html 跨域 前后分离
    springcloud 项目源码 微服务 分布式 Activiti6 工作流 vue.js html 跨域 前后分离
    OA办公系统 Springboot Activiti6 工作流 集成代码生成器 vue.js 前后分离 跨域
    java企业官网源码 自适应响应式 freemarker 静态引擎 SSM 框架
    java OA办公系统源码 Springboot Activiti工作流 vue.js 前后分离 集成代码生成器
    springcloud 项目源码 微服务 分布式 Activiti6 工作流 vue.js html 跨域 前后分离
    java 视频播放 弹幕技术 视频弹幕 视频截图 springmvc mybatis SSM
    最后阶段总结
    第二阶段学习总结
    第一阶段学习总结
  • 原文地址:https://www.cnblogs.com/xuting/p/2798765.html
Copyright © 2011-2022 走看看