吾爱破解 - 52pojie.cn

 找回密码
 注册[Register]

QQ登录

只需一步,快速开始

查看: 2156|回复: 5
上一主题 下一主题
收起左侧

[系统底层] win32笔记六 创建线程

[复制链接]
跳转到指定楼层
楼主
huchen 发表于 2024-4-22 00:32 回帖奖励
之前的索引


创建线程

说明:由于在win10主机找线程数有点麻烦(可能是我没找到简便的方法)这次的实验环境就全在虚拟机win xp了

什么是线程?

  1. 线程是附属在进程上的执行实体,是代码的执行流程
  2. 一个进程可以包含多个线程,但是一个进程至少要包含一个线程

在上面的学习中,得知进程至少有一个线程,不然这个进程就是死的,可以理解为进程就是4GB里的东西,是空间的概念,而线程就是时间的概念,代表着当前正在运行的代码

相信大家听过多线程,这是因为不止一个CPU即多核,但是单核即一个CPU能多线程吗?严格意义上讲不能,只是因为CPU切换进程的速度太快,而导致让人产生错觉,以为是两个进程同时在跑

小实验

#include<stdio.h>
#include<Windows.h>
int main()
{
    for (int i = 0 ; i < 100; i++)
    {
        Sleep(500);
        printf("----------%d\n", i);
    }
    return 0;
}

这里有个简单的代码,这个也是线程,当然要运行起来

可以看到运行起来后在管理器就有了他的身影,并且线程数是1,因为这里只有一段的执行代码

当执行完了后这个进程就死了,因为线程死了,在管理器中也看不到了

那如果我想在这个代码上还要在执行一个代码,即线程数加1

那么就要介绍新的API了

CreateThread

HANDLE CreateThread(
  LPSECURITY_ATTRIBUTES lpThreadAttributes, // SD
  DWORD dwStackSize,                        // initial stack size
  LPTHREAD_START_ROUTINE lpStartAddress,    // thread function
  LPVOID lpParameter,                       // thread argument
  DWORD dwCreationFlags,                    // creation option
  LPDWORD lpThreadId                        // thread identifier
);
lpThreadAttributes

安全描述符,以前的学习中介绍过,不多赘述

dwStackSize

创建线程的初始堆栈,每个线程都有堆栈,十个线程就有十个堆栈,那这堆栈是多少大小的?就是这个决定的,不填写,系统会默认分配好大小

lpStartAddress

当前的线程真正执行的代码在哪里

DWORD WINAPI ThreadProc(
  LPVOID lpParameter   // thread data
);

这是函数的类型

lpParameter

创建的lpStartAddress函数需要的参数,有个话就写个指针,没有就填空

dwCreationFlags

创建线程的标识

dwCreationFlags

[in] Specifies additional flags that control the creation of the thread. If the CREATE_SUSPENDED flag is specified, the thread is created in a suspended state, and will not run until the ResumeThread function is called. If this value is zero, the thread runs immediately after creation. At this time, no other values are supported.

这里有两个选项,一个是填0,填0的时候这个线程被创建出来以后可以立即执行,还有可以选择CREATE_SUSPENDED这个宏来创建这个线程,创建之后不会立即执行,而是挂起的状态,直到被ResumeThread函数唤醒

lpThreadId

lpThreadId*

[out] Pointer to a variable that receives the thread identifier.

可以看到这是个out参数,说明是会返回结果的,返回的是创建这个线程的线程ID

提一嘴,这个函数是有返回值的,可以接收的

介绍完了,开始代码

#include<stdio.h>
#include<Windows.h>

DWORD WINAPI ThreadProc(LPVOID lpParameter)
{
    for (int i = 0 ; i < 100; i++)
    {
        Sleep(500);
        printf("+++++++++++++++%d\n", i);
    }
    return 0;
}

int main()
{

    HANDLE hThread;
    hThread = CreateThread(NULL,0,ThreadProc,NULL,0,NULL);
    CloseHandle(hThread);

    for (int i = 0 ; i < 100; i++)
    {
        Sleep(500);
        printf("----------%d\n", i);
    }
    return 0;
}

运行结果

可以看到能运行,只是这俩进程没有默契一般,不是你一下,我一下的这种

这样的情况是正常的

如果想让两个线程之间达到这种默契,这就要了解线程通信的相关知识

这函数不是有返回结果吗?那如果不想弄返回值呢,试试

#include<stdio.h>
#include<Windows.h>

void WINAPI TestProc()
{
    for (int j = 0 ; j < 100; j++)
    {
        Sleep(500);
        printf("+++++++++++++++%d\n", j);
    }
}
int main()
{
    HANDLE hThread;
    hThread = CreateThread(NULL,0,TestProc,NULL,0,NULL);
    CloseHandle(hThread);
    for (int i = 0 ; i < 100; i++)
    {
        Sleep(500);
        printf("----------%d\n", i);
    }
    return 0;
}

提示我类型不匹配,那我强制转换呢?

hThread = CreateThread(NULL,0,(LPTHREAD_START_ROUTINE )TestProc,NULL,0,NULL);

就可以了,所以这个参数和返回值不是必须要按照他定义的那样,最多就是强制转换一下

回到本来的样子,可以看到创建线程的函数是有参数的,那这个参数有啥用呢?

以本代码为例,如果我想控制这个打印次数的话就可以用这个参数

#include<stdio.h>
#include<Windows.h>

DWORD WINAPI ThreadProc(LPVOID lpParameter)
{
    int* p = (int*)lpParameter;

    for (int i = 0 ; i < *p; i++)
    {
        Sleep(500);
        printf("+++++++++++++++%d\n", i);
    }
    return 0;
}

int main()
{
    int n=10;
    HANDLE hThread;
    hThread = CreateThread(NULL,0,ThreadProc,&n,0,NULL);
    CloseHandle(hThread);

    for (int i = 0 ; i < 100; i++)
    {
        Sleep(500);
        printf("----------%d\n", i);
    }
    return 0;

}

这里+符号就只打印十次

需要注意的是,在创建线程的时候,主函数的周期要比创建的久,也就是要活的久,这样才能让创建的线程跑完,或者定义成全局变量,这个一直都在

免费评分

参与人数 4吾爱币 +9 热心值 +4 收起 理由
asciibase64 + 1 谢谢@Thanks!
allspark + 1 + 1 用心讨论,共获提升!
willJ + 7 + 1 欢迎分析讨论交流,吾爱破解论坛有你更精彩!
xinxin99 + 1 + 1 用心讨论,共获提升!

查看全部评分

发帖前要善用论坛搜索功能,那里可能会有你要找的答案或者已经有人发布过相同内容了,请勿重复发帖。

沙发
dj8888 发表于 2024-4-23 09:10
这个好!!
3#
geyutong 发表于 2024-4-23 15:39
4#
巧言乱德 发表于 2024-4-23 16:16
头像被屏蔽
5#
hjsen 发表于 2024-4-24 19:51
提示: 作者被禁止或删除 内容自动屏蔽
您需要登录后才可以回帖 登录 | 注册[Register]

本版积分规则

返回列表

RSS订阅|小黑屋|处罚记录|联系我们|吾爱破解 - LCG - LSG ( 京ICP备16042023号 | 京公网安备 11010502030087号 )

GMT+8, 2024-11-21 16:02

Powered by Discuz!

Copyright © 2001-2020, Tencent Cloud.

快速回复 返回顶部 返回列表