C++ 多线程(二)Win32多线程1

C++ 多线程(二)Win32多线程1


概述

Microsoft Windows 操作系统对多线程编程的支持几乎类似于 POSIX 线程提供的支持。区别不在于实际的功能,而在于 API 函数中的名称。

每个 Win32 进程至少有一个线程,我们将其称为主线程。我们将假设操作系统将以循环方式为每个程序线程提供一个时间片。事实上,Win32 程序中的线程将与其他程序中的线程和系统线程竞争 CPU,而这些其他线程可能有更高的优先级。

让我们看一下这个简单的例子。

主线程会生成一个新线程来增加 myThread 函数内的myCounter,同时主线程会一直等待用户输入一个字符(getchar()),并在我们输入除 ‘q’ 字符以外的任何时候打印出计数器值:

要使用 Windows 多线程函数,我们必须包含<windows.h>。为了创建线程,Windows API 提供了 CreateThread() 函数。

每个线程都有自己的堆栈。你可以使用 stackSize 参数指定新线程堆栈的大小(以字节为单位),这是下面例子中 CreateThread() 函数的第二个参数。如果这个整数值是零,那么线程将被赋予一个与创建线程相同大小的堆栈。

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

DWORD WINAPI myThread(LPVOID lpParameter)
{
    unsigned int& myCounter = *((unsigned int*)lpParameter);
    while(myCounter < 0xFFFFFFFF) ++myCounter;
    return 0;
}

int main(int argc, char* argv[])
{
    using namespace std;

    unsigned int myCounter = 0;
    DWORD myThreadID;
    HANDLE myHandle = CreateThread(0,
                                   0, 
                                   myThread, 
                                   &myCounter, 
                                   0, 
                                   &myThreadID);

    char myChar = ' ';
    while (myChar != 'q') 
    {
        cout << myCounter << endl;
        myChar = getchar();
    }

    CloseHandle(myHandle);
    return 0;
}

输出是:

0
868171493
1177338657
3782005161
4294967295
4294967295
...

每个执行线程都从创建过程中调用一个称为线程函数的函数开始。CreateThread() 函数的第三个参数 myThread 是线程函数。线程继续执行,直到线程函数返回。这个函数的地址(也就是线程的入口点)在 threadFunc 中指定。

通过输入字符 ‘q’,我们可以结束程序。

创建 Windows 的线程

最基本的 Windows 应用程序从一个线程开始。我们用来创建子线程的函数调用是 CreateThread()。下面的语法显示了传递给 CreateThread()的参数。

HANDLE WINAPI CreateThread(
__in_opt LPSECURITY_ATTRIBUTES lpThreadAttributes,
__in SIZE_T dwStackSize,
__in LPTHREAD_START_ROUTINE lpStartAddress, 
__in_opt LPVOID lpParameter, 
__in DWORD dwCreationFlags,
__out_opt LPDWORD lpThreadId 
); 

参数

  1. lpThreadAttributes[输入参数, 可选]
    一个指向 SECURITY_ATTRIBUTES 结构的指针,该结构决定返回的句柄是否可以被子进程继承。如果 lpThreadAttributes 为 NULL,则不能继承该句柄。
    结构的 lpSecurityDescriptor 成员为新线程指定了一个安全描述符。如果 lpThreadAttributes 为 NULL,线程将获得默认的安全描述符。线程的默认安全描述符中的 ACL 来自创建者的主令牌。
  2. dwStackSize[输入参数]
    堆栈的初始大小,以字节为单位。系统将这个值舍入到最近的页面。如果此参数为零,则新线程将使用可执行文件的默认大小。
  3. lpStartAddress[输入参数]
    一个指针,指向要由线程执行的应用程序定义的函数。这个指针表示线程的起始地址。
  4. lpParameter[输入参数
  • 1
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

大鹏068

你的鼓励是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值