Windows线程(一)

线程启动

在进入main函数之前已经启动了线程(mainStartup)
这个线程是进程的主线程,它的入口函数默认的为main/WinMain
该入口函数可以在编译器中进行设置

用CreateThread函数创建线程
在线程创建时会创建线程内核对象,它是一个结构体,不代表线程本身,主要是便于Windows管理
会分配一块线程堆栈空间,每个线程都有自己的堆栈空间
HANDLE WINAPI CreateThread(
  _In_opt_   LPSECURITY_ATTRIBUTES lpThreadAttributes,//线程安全属性, 一般设置为NULL
  _In_       SIZE_T dwStackSize,//堆栈大小,为0时, 由编译器决定, 单位是BYTE
  _In_       LPTHREAD_START_ROUTINE lpStartAddress,//线程入口函数
  _In_opt_   LPVOID lpParameter,//线程参数
  _In_       DWORD dwCreationFlags,//创建标志
  _Out_opt_  LPDWORD lpThreadId//TID
);

线程入口函数

DWORD WINAPI ThreadProc(
  _In_  LPVOID lpParameter
);//线程入口函数的原型

堆栈大小的设置

通过设置dwStackSize参数来设置线程的堆栈大小
可以设置为0
这样就由编译器来决定堆栈的大小
在VisualStudio中可以进行设置, 默认是 1MB
当线程将自己所拥有的堆栈空间不够用时, 会抛出异常
这个异常会被捕获,再次重新自动重新分配新的栈

线程创建的标志

通过dwCreationFlags来设置线程的运行方式
0 
线程立即运行

CREATE_SUSPENDED
暂停状态, 线程不会运行, 除非调用ResumeThread方法

STACK_SIZE_PARAM_IS_A_RESERVATION
表示dwStackSize参数指定的是堆栈的初始保留大小
不指定此标志, dwStackSize将指定堆栈提交大小

线程的抢占式执行

线程的执行是并行的
线程执行的先后顺序是不确定的
可以使用Sleep函数让线程休眠,让出CPU时间片
DWORD WINAPI MyMain(LPVOID lParam)
{
    for(int i = 1; i < 101; ++i)
    {
        printf("%d\n", i);
    }
    return 0;
}

DWORD WINAPI MyMain1(LPVOID lParam)
{
    for (int i = 101; i < 201; ++i)
    {
        printf("%d\n", i);  
    }
    return 0;
}


int main()
{
    int i = -1;
    LPVOID lParam = LPVOID(i);
    HANDLE hThread[2];
    hThread[0] = CreateThread(nullptr, 0, MyMain, lParam, 0, nullptr);
    hThread[1] = CreateThread(nullptr, 0, MyMain1, lParam, 0, nullptr);

    for (int j = 201; j < 301; ++j)
    {
        printf("%d\n", j);
    }

    WaitForMultipleObjects(2, hThread, true, INFINITE);
    CloseHandle(hThread[0]);
    CloseHandle(hThread[1]);
    Sleep(100);
    return 0;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值