0x01.什么是线程?

1、线程是附属在进程上的执行实体,是代码的执行流程

进程 本身是空间上的概念,代表4GB的虚拟内存,线程代表着时间概念,也就是说,线程是当前运行的代码

在某个时间点只能有一段代码执行,但是cpu切换的快,所以看着像同时运行,这是单核的,所以单核的情况下并不是真正的多线程

因为线程执行的话是需要一套寄存器的,比如eax,ecx,ebx...

2、一个进程可以保护多个线程,但一个进程至少要包含一个线程



我们现在想创建一个线程了,其实main函数这边就是一个线程了,但是我们需要再创建一个呢?

需要使用到新的api,CreateThread

0x02. 创建线程

CreateThread(
LPSECURITY_ATTRIBUTES lpThreadAttributes, //安全描述符,判断子进程是否可以继续父进程的句柄表,NULL就可以了
IZE_T dwStackSize, //初始堆栈,如果不填写就会自动填写默认的
LPTHREAD_START_ROUTINE lpStartAddress, //当前的线程要执行的代码
__drv_aliasesMem LPVOID lpParameter, //要创建的线程的参数,这是个指针
DWORD dwCreationFlags, //创建线程的标识
LPDWORD lpThreadId //这个是OUT类型参数,这个参数说明是往外传递结果的,这个就是返回创建的线程ID,返回值是当前线程的句柄
);

dwCreationFlags标识:

由于是返回值是句柄,所以我们要声明一个句柄变量进行接收,也可以不接收

CloseHandle()不想用的话可以用这个函数关闭,但是这里的关闭其实是减掉一个计数器

线程的内核对象计数器为0也不会关闭,关闭线程的两个必要条件

①、线程的内核对象计数器为 0

②、线程的执行代码执行完毕了

#include <stdio.h>
#include <windows.h> int main()
{
HANDLE hThread = CreateThread(NULL, 0, 0, NULL, 0, NULL); CloseHandle(hThread); for (int i = 0; i < 100; i++)
{
Sleep(500);
printf("------- %d --------\n", i); } getchar();
return 0;
}

所以我们这边CloseHandle掉线程也是没有影响的,并不会影响到线程,因为当前代码没执行完后是没有人能关掉的

然后看向CreateThread的第三个参数:lpStartAddress

而这个参数是要执行的代码,然而这个代码是不能随便乱写的,是有格式的

#include <stdio.h>
#include <windows.h> DWORD WINAPI ThreadProc(LPVOID lpParameter)
{ return 0;
} int main()
{
HANDLE hThread = CreateThread(NULL, 0, 0, NULL, 0, NULL); CloseHandle(hThread); for (int i = 0; i < 100; i++)
{
Sleep(500);
printf("------- %d --------\n", i); } getchar();
return 0;
}

然后我们在这个ThreadProc函数中写上代码,我们依然写入for循环来

然后基本就类似是同时运行的,所以以后每创建一个线程就必须要使用 CreateThread函数来

这个函数就是告诉代码在哪里,返回值啥的就需要强转就可以了

这时候我们想指定线程循环的次数呢?

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

在ThreadProc() 函数内小改动一下,main函数中指定一下要几次

int main()
{
int n;
n = 10;
HANDLE hThread = CreateThread(NULL, 0, ThreadProc, (LPVOID)&n, 0, NULL); CloseHandle(hThread); for (int i = 0; i < 100; i++)
{
Sleep(500);
printf("------- %d \n", i); } getchar();
return 0;
}

线程参数可以传任何参数,传进去后转型一下就好了,然后运行一下,发现成功了

Win32之创建线程的更多相关文章

  1. c++ Pthread创建线程后必须使用join或detach释放线程资源

    http://www.cppblog.com/prayer/archive/2012/04/23/172427.html 这两天在看Pthread 资料的时候,无意中看到这样一句话(man pthre ...

  2. 在Delphi中创建线程,请一定使用BeginThread()代替CreateThread()创建线程!(更好的管理异常)

    在Delphi中创建线程,请一定使用BeginThread()代替CreateThread()创建线程! 如果直接使用Win32的API函数CreateThread()创建多个线程,也是可以创建的.但 ...

  3. 0036 Java学习笔记-多线程-创建线程的三种方式

    创建线程 创建线程的三种方式: 继承java.lang.Thread 实现java.lang.Runnable接口 实现java.util.concurrent.Callable接口 所有的线程对象都 ...

  4. [笔记]linux下和windows下的 创建线程函数

    linux下和windows下的 创建线程函数 #ifdef __GNUC__ //Linux #include <pthread.h> #define CreateThreadEx(ti ...

  5. Java学习笔记-多线程-创建线程的方式

    创建线程 创建线程的方式: 继承java.lang.Thread 实现java.lang.Runnable接口 所有的线程对象都是Thead及其子类的实例 每个线程完成一定的任务,其实就是一段顺序执行 ...

  6. python:threading多线程模块-创建线程

    创建线程的两种方法: 1,直接调用threading.Thread来构造thread对象,Thread的参数如下: class threading.Thread(group=None, target= ...

  7. 【java并发】传统线程技术中创建线程的两种方式

    传统的线程技术中有两种创建线程的方式:一是继承Thread类,并重写run()方法:二是实现Runnable接口,覆盖接口中的run()方法,并把Runnable接口的实现扔给Thread.这两种方式 ...

  8. Java并发编程:如何创建线程?

    Java并发编程:如何创建线程? 在前面一篇文章中已经讲述了在进程和线程的由来,今天就来讲一下在Java中如何创建线程,让线程去执行一个子任务.下面先讲述一下Java中的应用程序和进程相关的概念知识, ...

  9. 驱动开发之 创建线程函数PsCreateSystemThread

    PsCreateSystemThread 创建一个执行在内核模式的系统线程. 注意:创建线程必须用函数PsTerminateSystemThread强制线程结束.否则该线程是无法自动退出的. 函数原型 ...

随机推荐

  1. JS实现简单的多选选项的全选反选按钮

    1 <!DOCTYPE html> 2 <html> 3 <head lang="en"> 4 <!-- 5 需求: 6 1.写三个按钮: ...

  2. Python练习题 018:打印星号菱形

    [Python练习题 018] 打印出如下图案(菱形): * *** ***** ******* ***** *** * --------------------------------------- ...

  3. Asp.Net Core 企业微信静默授权

    企业微信接口文档 1.构造授权网页链接 2.回调获取到 Code 通过code+access_token去请求用户信息 3.获取access_token 调试准备工作 -->内网穿透+域名 推荐 ...

  4. .NET Standard 系列

    .NET Standard 是一套正式的 .NET API 规范,有望在所有 .NET 实现中推出. 推出 .NET Standard 的背后动机是要提高 .NET 生态系统中的一致性. ECMA 3 ...

  5. 在自己电脑上查看git远程分支列表比实际云端的远程分支要多一些

    问题 最近打开一个很久没有打开过的项目,使用git branch -a查看了一下所以分支,其中有些远程分支没有什么用了 于是准备去gitlab上删除它,结果到gitlab上发现没有这些分支,猜测是自己 ...

  6. Git命令diff格式详解

    diff是Unix系统的一个很重要的工具程序. 它用来比较两个文本文件的差异,是代码版本管理的基石之一.你在命令行下,输入: $ diff <变动前的文件> <变动后的文件> ...

  7. Rust之路(2)——数据类型 上篇

    [未经书面同意,严禁转载] -- 2020-10-13 -- Rust是系统编程语言.什么意思呢?其主要领域是编写贴近操作系统的软件,文件操作.办公工具.网络系统,日常用的各种客户端.浏览器.记事本. ...

  8. day15 Pyhton学习

    迭代器 掌握for循环 实际上for循环的本质,就是将一个可迭代的变成迭代器 每一次从中取值都相当于执行了一次next 如果是迭代器,那么只能取一次值 生成器 - 本质就是迭代器 生成器函数(返回值是 ...

  9. Presto在滴滴的探索与实践

    ​桔妹导读:Presto在滴滴内部发展三年,已经成为滴滴内部Ad-Hoc和Hive SQL加速的首选引擎.目前服务6K+用户,每天读取2PB ~ 3PB HDFS数据,处理30万亿~35万亿条记录,为 ...

  10. golang通过cgo调用lua

    目录 1.前期准备 2.测试go代码 3.完成的一个学习项目 4.总结 1.前期准备 1.第三方库:https://github.com/aarzilli/golua 2.下载lua源码:https: ...