【windows】关于频繁创建和关闭进线程开销大的原因理解之一(1)
首先从进程角度去看,内部其实是由一个或者若干个线程组成。因此在理解进程频繁创建和关闭导致的开销问题,只需要理解一个单一线程的频繁创建和关闭即可。
CreateThread、TerminateThread
这两个函数一个用于创建线程,另一个用于关闭线程。
1,先说一下线程创建的过程。对于CreateThread来说,创建的均为用户态线程。尽管创建的是用户态线程,但对于函数被调用者来说,本身还是需要切换到内核态或等待内核态服务线程将线程创建起来。
仅从这一点去看,有了态切换。显然就存在各种开销。
2,在内核创建好线程以后,这个线程将会被纳入windows的线程调度中,同时该线程所占有的内存资源也会被纳入内存调度中。仅从这里去看,又可以看到两个调度器的任务增加,且内存资源在减小。
3,在线程退出后,内核需要对其内存进行回收。在回收过程中,需要对线程的堆栈等系统分配给的内存资源进行校验(退出时的crash生成也在这一步)。检查完成以后,又要将回收回来的内存插回到windows的堆栈管理器里面(不管是crt堆,还是win32堆或者系统堆,都要插回去)。在回插内存的时候,可能还会引发堆内存的合并和子堆往父堆进行归还的过程。
通过以上描述,基本可得知线程的创建和关闭的开销是相当大的事情。
如果再深入一点看的话,可能会更清楚一些。
由于在windows系统以后,系统会“虚拟”出一个system进程,该进程内部其实是一堆辅助线程(有时候创建IO句柄时,也会出现这个进程里面的线程数增加,或者做调试的时候也有可能会出现类似的现象)。
system里面的线程,主要是用于服务在不同IRQL和内核用户态之间。换句话说,相当于一个桥(个人猜测,不负责哈!)。
当一个线程要进行关闭时,该system里面的辅助线程(15级以上),会对线程回收工作进行处理。换句话说,如果一个线程自己是正常退出的,那么自己会抛一个系统请求给system,让system把自己的内存回收掉。这个过程又要走一堆windows服务程序(服务端口),从这一点上看可得知。
一个线程的关闭,势必会激活一个“紧急”任务的进行,且会涉及到一个较长的流程。应此无论是创建还是关闭线程,如果执行频度太过于高,显然是不行的。