即所谓的线程池

时间:2021-11-27 02:35:53

完成端口(Completion Port)

 完成端口是Win32一种核心东西。操作完成端口模型,套接字应用措施能够打点数百个甚至上千个套接字。应用措施创建一个Win32完成端口东西,通过指定必然数量的处事线程,为已经完成的重叠I/O操纵供给处事。该模型往往可以到达最好的系统性能。

 完成端口是真正意义上的异步模型。该模型解决了“one-thread-per-client”的问题。当应用措施需要打点成百上千个套接字,并且但愿跟着系统安置的CPU数量的增加,应用措施的性能得到提升时,I/O完成端口模型是最好的选择。

处事器线程模型:

        处事器有两种线程模型:串行模型和并发模型 串行模型单个线程期待客户真个请求。当请求到来时,该线程醒来措置惩罚惩罚请求。该模型应用于简单的处事器措施。处事器接受的请求对照少,接受的请求能被很快地措置惩罚惩罚。

        该模型的错误谬误在于:当多个客户端同时向处事器发出请求时,这些请求必需依次被接受。例如:两个客户端同时向处事器发出请求,第二个请求必需在第一个请求措置惩罚惩罚完毕后,才华被接受。 并发模型:单个线程期待客户端请求,当请求到来时,创建新线程来措置惩罚惩罚请求。期待客户请求的线程继续期待另一个客户端请求。新线程措置惩罚惩罚完客户端请求撤退退却出。 处事器线程模型为每个客户端创建一个新线程,客户端请求能够很快地措置惩罚惩罚。由于每个客户端请求都有本身的线程,所以处事器措施的伸缩性对照好。当升级硬件时,处事器措施的性能可以得到提高。

并发模型的不敷:

通过上面的分析,串行模型不适合开发高效的处事器措施,而并发模型对照适合,但是并发模型也存在如下的不敷:

并不是每个客户端请求都创建一个线程,就必然会提高套接字应用措施的性能。因为当处事器创建许多线程时,系统内核进行线程上下文会花费很多时间,而线程没有足够的时间为客户端处事。

并发模型在接受客户端请求后,创建一个新的线程,当处事结束后,使线程退出。当新的客户端请求到来时,再创建新的线程。这样不停地创建和销毁线程,会增加系统的开销。

完成端口方针是实现高效的处事器措施,他克服了并发模型的不敷。其要领一是为完成端口指定并发线程的数量;二是在初始化套接字时创建必然数量的处事线程,即所谓的线程池。当客户端请求到来时,这些线程当即为之处事。

完成端口的理论根本是并行运行的线程数量必需有一个上限。这个数值就是CPU的个数。如果一台机器有两个CPU,那么多于两个可运行的线程就没有意义了。因为一旦运行线程数目超过CPU数目,系统就不得花费时间来进行线程上下文的切换,这将浪费名贵的CPU周期。

完成端口并行运行的线程数目和应用措施创建的线程数量是两个差此外观点。

处事器应用措施需要创建几多个处事器线程,一般规律是CPU数目乘以2.例如,单CPU的机器,套接字应用措施应该创建2个线程的线程池。

接下来的问题是,完成端口如何实现对线程池的有效打点,使这些处事线程高效运行起来。

当系统完成I/O操纵后,向处事器完成端口发送I/O completion packet。这个过程产生在系统内部,对应用措施是不偏见的。在应用措施方面,此时线程池中的线程在完成端口上排队期待I/O操纵完成。如果在完成端口上没有接收到I/O completion packet时,这些线程处于睡吧状态。当I/O completion packet 被送到完成端口时,这些线程凭据后进先出(LIFO Last-in-First-out)方法被唤醒。

完成端口之所以给与这种方法,其目的是为了提高性能。例如,有3个线程在完成端口上期待,当一个I/O completion packet达到后,队中最后一个线程被唤醒。

该线程为客户端完成处事后,继续在完成端口上期待。如果 此时又有一个I/O completion packet 达到完成端口,则该线程线程又被唤醒,为该客户端供给处事。如果完成端口不给与LIFO方法,完成端口唤醒此外一个线程,则一定要进行线程之间的上下文切换。通过使用LIFO方法,还可以使得不被唤醒的线程内存资源从缓存中断根 。

在前面讲到的,应用措施需要创建一个线程池,在完成端口上期待。线程池中的线程数目必然大于完成端口并发运行的线程数目,似乎应用措施创建了多余的线程,其实不然,之所以这样做是因为保证CPU尽可能的忙碌。

例如,在一台单CPU的计算机上,创建一个完成端口的应用措施,为其制定并发线程数目为1.在应用措施中,创建2个线程在完成端口上期待。假如在一次为客户端处事时,被唤醒的线程因挪用Sleep()之类的函数而处于梗阻状态,此时,此外一个I/O completion packet 被发送到完成端口上。完成端口会唤醒此外一个线程为该客户供给处事。这就是线程池中线程数目要大于完成端口指定的并发线程数量的原因。