“主线程”探究,谈谈我对“主线程”的理解

   今天看到论坛上有人问关于”主线程“的问题,写篇文章来谈谈自己的看法。

  我认为”主线程“是一个经验概念,所谓经验概念,就是说程序员印象中有这么个东西,但是在系统层面,并没有对线程进行”主“和”辅“的区分。为什么大家会有这种”主线程“的概念的,可能是由于常见的编程框架如MFC、VCL、包括SDK都存在一个共同的特点,从某个函数开始执行,这个函数执行完毕后,程序退出。那么这个函数所在的线程就可以称之为”主线程“。

  对于MFC,这个函数可以是CMyApp::InitializeInstance;对于VCL,这个函数可以是dpr文件中的begin和end之间的部分;对于SDK,这个函数可以是man函数或者WinMain函数。但所有这些函数都并非程序真正的入口点。

  VC编译的可执行程序,入口点无外乎四个:

mainCRTStartup             CUI程序的入口点

wmainCRTStartup          基于UNICODE的CUI程序的入口点

WinMainCRTStartup      GUI程序的入口点

wWinMainCRTStartup   基于UNICODE的GUI程序的入口点

  这些入口点函数的实现代码就在C库源码中,查看这些代码最简单的办法就是在VC环境中调试运行你的程序,暂停到主函数的某一行,然后查看调用栈,真正的入口点函数就在栈的下方某个位置(前提是安装VC的时候选择同时安装C库源代码)。

  这些C库内建的入口点函数做的事情主要是初始化全局变量,调用主函数,析构全局变量和其他一些操作,最终调用ExitProcess函数退出进程(从这里可以看到,全局对象的构造函数会早于主函数执行)。也就是说,有一个线程调用了主函数,也负责最终程序的退出,这就是经验中的”主线程“。

  ”进程中的所有线程都退出,程序才会退出“,错,只要有一个线程调用了ExitProcess终止进程,进程就会退出,不必等候其他线程。终止进程的可以是”主线程“,也可以是某一个平凡的线程。

  一个例子:

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

//修改入口点为我们的自定义函数
#pragma comment(linker, "/Entry:SlxEntry")

DWORD __stdcall Thread(LPVOID lpParam)
{
    DWORD dwEntryThreadId = (DWORD)lpParam;
    DWORD dwCurrentThreadId = GetCurrentThreadId();
    DWORD dwIndex;

    printf("  本工作线程%lu由主线程%lu创建,开始执行...\n", dwCurrentThreadId, dwEntryThreadId);

    for (dwIndex = 0; dwIndex < 10; dwIndex += 1)
    {
        printf("  工作线程%lu工作中%lu...\n", dwCurrentThreadId, dwIndex + 1);
        Sleep(1000);
    }

    printf("  工作线程%lu退出...\n", dwCurrentThreadId);
    return 0;
}

VOID SlxEntry()
{
    HANDLE hThread;
    DWORD dwWorkThreadId = 0;
    DWORD dwCurrentThreadId = GetCurrentThreadId();

    printf("主线程%lu开始...\n", dwCurrentThreadId);

    hThread = CreateThread(NULL, 0, Thread, (LPVOID)dwCurrentThreadId, 0, &dwWorkThreadId);
    CloseHandle(hThread);

    printf("创建工作线程%lu...\n", dwWorkThreadId);
    printf("主线程%lu退出...\n", dwCurrentThreadId);
}
  入口点线程(即”主线程“)退出了,但是工作线程还在,进程不会退出。


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值