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

本文探讨了在编程中关于主线程的概念,指出这更多是一种经验性的说法而非系统层面的正式定义。通过分析常见编程框架(如MFC、VCL及SDK)的特点,明确了所谓的主线程通常指启动并最终结束程序的线程。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

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

  我认为”主线程“是一个经验概念,所谓经验概念,就是说程序员印象中有这么个东西,但是在系统层面,并没有对线程进行”主“和”辅“的区分。为什么大家会有这种”主线程“的概念的,可能是由于常见的编程框架如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终止进程,进程就会退出,不必等候其他线程。终止进程的可以是”主线程“,也可以是某一个平凡的线程。

  一个例子:

  1. #include <Windows.h>  
  2. #include <stdio.h>  
  3.   
  4. //修改入口点为我们的自定义函数  
  5. #pragma comment(linker, "/Entry:SlxEntry")  
  6.   
  7. DWORD __stdcall Thread(LPVOID lpParam)  
  8. {  
  9.     DWORD dwEntryThreadId = (DWORD)lpParam;  
  10.     DWORD dwCurrentThreadId = GetCurrentThreadId();  
  11.     DWORD dwIndex;  
  12.   
  13.     printf("  本工作线程%lu由主线程%lu创建,开始执行...\n", dwCurrentThreadId, dwEntryThreadId);  
  14.   
  15.     for (dwIndex = 0; dwIndex < 10; dwIndex += 1)  
  16.     {  
  17.         printf("  工作线程%lu工作中%lu...\n", dwCurrentThreadId, dwIndex + 1);  
  18.         Sleep(1000);  
  19.     }  
  20.   
  21.     printf("  工作线程%lu退出...\n", dwCurrentThreadId);  
  22.     return 0;  
  23. }  
  24.   
  25. VOID SlxEntry()  
  26. {  
  27.     HANDLE hThread;  
  28.     DWORD dwWorkThreadId = 0;  
  29.     DWORD dwCurrentThreadId = GetCurrentThreadId();  
  30.   
  31.     printf("主线程%lu开始...\n", dwCurrentThreadId);  
  32.   
  33.     hThread = CreateThread(NULL, 0, Thread, (LPVOID)dwCurrentThreadId, 0, &dwWorkThreadId);  
  34.     CloseHandle(hThread);  
  35.   
  36.     printf("创建工作线程%lu...\n", dwWorkThreadId);  
  37.     printf("主线程%lu退出...\n", dwCurrentThreadId);  
  38. }  

  入口点线程(即”主线程“)退出了,但是工作线程还在,进程不会退出。


转自:http://blog.youkuaiyun.com/my3439955/article/details/8909641

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值