Win32多线程程序设计

Win32多线程程序设计

”多线程多任务“是程序开发者和用户都需要的一个重要资产。从WindowsNT开始,完全支持32位程序的抢占式多任务。带领我们进入了”多线程多任务“时代。

基本概念
进程(processes)
从win32角度来看,进程含有内存和资源,被进程拥有的内存理论上可达2GB,资源包括内核对象(handle,mutex…),user资源(对话框,字符串…),GDI资源(cdc和brush…)。
内存(memory)
每个进程存储数据的地方,分为:

  • Code | 存储程序代码
  • Data | 存储 全局变量,静态变量
  • Stack | 存储函数调用,线程分配的堆栈空间

线程(thread)
执行任务的载体

为什么程序不用多进程?
多线程:

  1. 线程廉价;
  2. 线程启动,退出快;
  3. 线程对系统资源冲击小;
  4. .线程对大部分内核对象有拥有权;

多进程:

  1. 耗费系统
  2. 程序窗口不易共享句柄

Win32线程创建
不使用C Run-time Library的多线程示例

#include <windows.h>
#include <tchar.h>
#include <Strsafe.h>

#define MAX_THREADS 5//线程数
#define BUF_SIZE 1024

DWORD WINAPI ThreadFun(LPVOID lpParam)
{
    TCHAR msgBuf[BUF_SIZE];
    size_t msgLen;
    DWORD dwChars;

    //线程参数取得
    int n = *(int*)lpParam;

    //输出到stdout
    HANDLE hStdOut = ::GetStdHandle(STD_OUTPUT_HANDLE);
    ::StringCchPrintf(msgBuf, BUF_SIZE, TEXT("%d%d%d%d%d%d%d%d%d%d\n"),
        n, n, n, n, n, n, n, n, n, n);
    ::StringCchLength(msgBuf, BUF_SIZE, &msgLen);

    for (int i = 0; i < 5; i++)
    {
        ::WriteConsole(hStdOut, msgBuf, msgLen, &dwChars, NULL);
    }
    return 0;
}

int _tmain(int argc, _TCHAR* argv[])
{
    HANDLE hThread[MAX_THREADS];
    DWORD dwThreadId;
    //线程创建
    for (int i = 0; i < MAX_THREADS; i++)
    {
        hThread[i] = (HANDLE)::CreateThread(
            NULL,
            0,
            ThreadFun,
            &i,
            0,
            &dwThreadId);
        if (hThread[i] != NULL)
        {
            printf("Thread launched %d\n", i);
        }
    }
    //等待所有线程结束
    ::WaitForMultipleObjects(MAX_THREADS, hThread, TRUE, INFINITE);

    //关闭结束线程句柄
    for (int i = 0; i < MAX_THREADS; i++)
    {
        ::CloseHandle(hThread[i]);
    }

    return 0;
}

使用C Run-time Library的多线程示例

#include <stdio.h>
#include <Windows.h>
#include <process.h>
//线程数
#define MAX_THREADS 5

unsigned int WINAPI ThreadFun(LPVOID lpParam)
{
    int n = *(int*)lpParam;
    for (int i = 0; i < 5; i++)
    {
        printf("%d%d%d%d%d%d%d%d%d%d\n", n, n, n, n, n, n, n, n, n, n);
    }
    return 0;
}

int _tmain(int argc, _TCHAR* argv[])
{
    HANDLE hThread[MAX_THREADS];
    unsigned int dwThreadId;
    //线程创建
    for (int i = 0; i < MAX_THREADS; i++)
    {
        hThread[i] = (HANDLE)::_beginthreadex(
            NULL,
            0,
            ThreadFun,
            &i,
            0,
            &dwThreadId);
        if (hThread[i] != NULL)
        {
            printf("Thread launched %d\n", i);
        }
    }
    //等待所有线程结束
    ::WaitForMultipleObjects(MAX_THREADS, hThread, TRUE, INFINITE);

    //关闭结束线程句柄
    for (int  i = 0; i < MAX_THREADS; i++)
    {
        ::CloseHandle(hThread[i]);
    }

    return 0;
}

区别使用C Run-time Library:
以上使用C Run-time Library和未使用C Run-time Library并非很严格,因为程序的startup就是从C Run-time Library开始执行,所以严格不使用C Run-time Library是不存在。那么只要满足下面情况,我们就认为是使用了C Run-time Library

  1. 在C程序中使用了malloc()和free(),或者在C++中使用了new和delete。
  2. 调用了stdio.h或者io.h中声明的任何函数,包括fopen open getchar write read。
  3. 使用浮点变量或者浮点运算函数
  4. 调用任何一个使用静态缓冲区的runtime函数,如asctime(),strtok(),rand();

如何正确函数创建Win32线程?
未使用C Run-time Library,利用CreateThread()函数创建线程,使用了C Run-time Library,利用_beginthreadex()函数创建线程,MFC程序中使用CWinThread创建线程。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值