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;
}

本片文章篇幅不长,欢迎交流
原文地址:https://www.cnblogs.com/xuting/p/2798765.html