• Win32之创建线程


    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 --------
    ", 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 --------
    ", 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 
    ", 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 
    ", i);
    
    	}
    
    	getchar();
    	return 0;
    }
    
    

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

  • 相关阅读:
    CodeForces 408E Curious Array(组合数学+差分)
    CodeForces 519E A and B and Lecture Rooms(倍增)
    洛谷 4051 [JSOI2007]字符加密(后缀数组)
    哇,两门学考都是A(〃'▽'〃)
    BZOJ 1977 严格次小生成树
    XJOI 3606 最大子矩形面积/LightOJ 1083 Histogram(单调栈/笛卡尔树)
    XJOI 3629 非严格次小生成树(pqq的礼物)
    XJOI 3363 树4/ Codeforces 739B Alyona and a tree(树上差分+路径倍增)
    [转载]别让用户发呆—设计中的防呆策略
    Linux下的链接文件
  • 原文地址:https://www.cnblogs.com/0x7e/p/13827456.html
Copyright © 2020-2023  润新知