CN112114955B - Windows平台下实现单进程单线程完成端口的方法 - Google Patents
Windows平台下实现单进程单线程完成端口的方法 Download PDFInfo
- Publication number
- CN112114955B CN112114955B CN202011038746.3A CN202011038746A CN112114955B CN 112114955 B CN112114955 B CN 112114955B CN 202011038746 A CN202011038746 A CN 202011038746A CN 112114955 B CN112114955 B CN 112114955B
- Authority
- CN
- China
- Prior art keywords
- function
- completion port
- port
- parameter
- thread
- Prior art date
- Legal status (The legal status is an assumption and is not a legal conclusion. Google has not performed a legal analysis and makes no representation as to the accuracy of the status listed.)
- Active
Links
Images
Classifications
-
- G—PHYSICS
- G06—COMPUTING; CALCULATING OR COUNTING
- G06F—ELECTRIC DIGITAL DATA PROCESSING
- G06F9/00—Arrangements for program control, e.g. control units
- G06F9/06—Arrangements for program control, e.g. control units using stored programs, i.e. using an internal store of processing equipment to receive or retain programs
- G06F9/46—Multiprogramming arrangements
- G06F9/48—Program initiating; Program switching, e.g. by interrupt
- G06F9/4806—Task transfer initiation or dispatching
- G06F9/4843—Task transfer initiation or dispatching by program, e.g. task dispatcher, supervisor, operating system
- G06F9/4881—Scheduling strategies for dispatcher, e.g. round robin, multi-level priority queues
-
- G—PHYSICS
- G06—COMPUTING; CALCULATING OR COUNTING
- G06F—ELECTRIC DIGITAL DATA PROCESSING
- G06F9/00—Arrangements for program control, e.g. control units
- G06F9/06—Arrangements for program control, e.g. control units using stored programs, i.e. using an internal store of processing equipment to receive or retain programs
- G06F9/46—Multiprogramming arrangements
- G06F9/50—Allocation of resources, e.g. of the central processing unit [CPU]
- G06F9/5005—Allocation of resources, e.g. of the central processing unit [CPU] to service a request
- G06F9/5027—Allocation of resources, e.g. of the central processing unit [CPU] to service a request the resource being a machine, e.g. CPUs, Servers, Terminals
Landscapes
- Engineering & Computer Science (AREA)
- Software Systems (AREA)
- Theoretical Computer Science (AREA)
- Physics & Mathematics (AREA)
- General Engineering & Computer Science (AREA)
- General Physics & Mathematics (AREA)
- Computer And Data Communications (AREA)
Abstract
本发明提供了一种Windows平台下实现单进程单线程完成端口的方法,属于计算机编程技术领域。该方法在使用完成端口时,在线程中使用GetQueuedCompletionStatus阻塞等待完成端口的事件发生,并根据GetQueuedCompletion Status参数中返回的信息处理相应的操作,这一过程放到主线程完成,同时使GetQueuedCompletionStatus不阻塞,在绑定完成端口时将线程数设置为1,从而实现单进程单线程完成端口。
Description
技术领域
本发明涉及计算机编程技术领域,尤其涉及一种Windows平台下实现单进程单线程完成端口的方法。
背景技术
在网络通信模型中,涉及到几个概念,同步、异步、阻塞和非阻塞。同步函数一般指调用函数后,等到函数功能实现再返回,期间一直霸占的CPU,等待期间同一个线程无法执行其他函数。异步函数指调用函数后,不管函数功能是否实现,立马返回;通过回调函数等告知函数功能完成。调用某些函数阻塞是因为函数功能没有实现,主动放弃CPU,让其他线程的得以执行;当功能实现后,函数返回;调用某些函数不会进入阻塞,无论实现与否,都会返回结果。
Windows下面的网络通信模型主要有以下几种:
1.select模型,为定期检查模型。一个线程用于accept客户端的接入,一个线程用于select数据的收发。该模型接收客户端连接属于同步(阻塞)模式,数据收发属于异步模式。
2.WSAAsyncSelect模型,为窗口事件通知模型。在一个线程中,将客户端socket和hWnd窗口句柄的消息事件关联,通过FD类别事件来识别客户端socket以及数据的接收和发送。这是一种异步通信实现,可以为多线程,也可以为单线程。
3.WSAEventSelect模型,为事件对象通知(选择)模型。一个线程用于accept客户端接入,创建事件对象并关联到客户端socket描述符。另一个线程使用WSAWaitForMultipleEvents来等待事件发生并处理读写数据。该模型接收客户端连接属于同步(阻塞)模式,数据收发属于异步模式。
4.重叠Overlapped IO模型,为多线程重叠IO和事件对象完成通知。一个线程用于accept客户端的接入,参照上述3,创建事件对象并关联到客户端socket,使另一个线程通过WSAWaitForMultipleEvents,得到处理完成数据的关联事件对象。然后通过WSAGetOverlappedResult得到重叠IO事件返回的结果以进一步选择如何处理数据。该模型接收客户端连接属于同步(阻塞)模式,数据收发属于异步模式。
5.完成端口IO Completion Port模型,通过完成端口消息队列有效的管理外部和内部的线程池,进而提高网络通信效率的模型。创建线程池,然后,基于完成端口队列事件通知机制,利用重叠IO,等待内部IO完成之后,再通知到等待事件的线程池。这是一种完美的非阻塞的、异步的、超高效的网络通信模式。
现在存在着一个应用场景:需要创建多个进程,但是每个进程只使用一个主线程,并且需要使用类似完成端口的机制来尽最大可能提升网络数据收发的吞吐率。
基于这一应用场景,上面列举的网络通信模型的缺陷:
1.select模型,可以设置为非阻塞模式,但是需要不断轮询检测,效率较低,并且有数量限制,不建议使用。
2.WSAAsyncSelect模型,是一种异步非阻塞模式,但是网络IO效率明显低下。
3.WSAEventSelect模型,接入客户端是阻塞模式,无法应用。
4.重叠Overlapped IO模型,效率较高,但是需要阻塞等待事件,无法应用。
5.完成端口IO Completion Port模型,网络数据收发的吞吐率足够,但是需要创建一个线程池(创建一个线程的线程池,那也是创建了新的线程,跟应用场景不符)。
中国专利申请文献CN107526645A中,公开了一种通信优化方法及系统,所述的方法包括:S1,为每一个客户端进程创建对应的命名管道;S2,将所有的命名管道句柄绑定到服务器的完成端口上,其中,完成端口运行于后台线程中;S3,通过完成端口获取每一个命名管道上的异步I/O操作,并根据每一个异步I/O操作的类型,调用相应的函数方法进行处理。该方法通过创建一个完成端口,将与客户端进程对应的所有命名管道句柄都绑定到完成端口上,利用完成端口来管理所有客户端的异步I/O操作,而完成端口只需要在一个后台线程中运行即可,因此,实现了通过一个后台线程就可以处理多个客户端的请求事件,相比传统的需要多个线程,避免了线程阻塞的问题,以及提高了CPU的处理效率。该方法实现了单线程完成端口关联过的客户端的异步I/O操作,避免了阻塞。但是,该发明用于多个客户端创建命名管道并绑定一个后台程序(该文件中描述为后台线程,事实上是在一个后台进程中)的完成端口上,该方法使用了完成端口技术,并且该发明运行于后台线程中,很明显,是在一台机器上面进行数据处理,该发明的目的是为了处理多个需要创建线程的业务逻辑,将多个业务逻辑分散到了不同的客户端程序中,从而避免了线程数据同步时的线程阻塞(同步)。该发明需要多个客户端进程(很可能有多个线程)和后台进程(很可能也是有多个线程的)来实现一种业务上的防止阻塞的技术。
现有技术至少存在以下不足:
1.select模型虽然能实现单进程单线程,但是相对于完成端口技术,不断轮询,效率极其低下。
2.WSAEventSelect模型和重叠Overlapped IO模型,都涉及accept阻塞,不适用于实现单进程单线程的完成端口模型。
3.WSAAsyncSelect模型网络IO效率低下,不适用于实现单进程单线程的完成端口模型。
4.完成端口IO Completion Port模型,网络数据收发的吞吐率足够,但需要创建线程池,不适用于实现单进程单线程的完成端口模型
发明内容
为解决现有技术中存在的技术问题,本发明提供了Windows平台下实现单进程单线程完成端口的方法,在完成端口的使用中,将在线程中使用GetQueuedCompletionStatus阻塞等待完成端口的事件发生,并根据GetQueuedCompletionStatus参数中返回的信息处理相应的操作,这一过程放到主线程完成,同时使GetQueuedCompletionStatus不阻塞,在绑定完成端口时将线程数设置为1,从而实现单进程单线程完成端口。
完成端口的使用过程大致如下:
1.创建完成端口;
2.按照逻辑CPU个数创建线程池,并将完成端口的句柄传入;
3.绑定服务端的监听socket到完成端口;
4.投递accept_ex操作事件到完成端口队列;
5.在线程中使用GetQueuedCompletionStatus阻塞等待完成端口的事件发生,并进行处理;
此时,数据已经准备好,你只需要直接对数据进行处理即可;并根据GetQueuedCompletionStatus参数中返回的信息,来对操作做相应的处理。
6.不断重复上面第5步的操作。
根据完成端口的使用过程,如果将上面第5步的操作移到主线程,同时解决两个问题:一是使用GetQueuedCompletionStatus不能阻塞,二是,在绑定完成端口时结合CPU的个数进行设置。
本发明需要用到完成端口的几个函数,下面对几个函数进行说明。
CreateIoCompletionPort()函数用来创建完成端口,参数NumberOfConcurrentThreads,表示当前运行的线程数。本发明要实现单进程单线程,因此,在使用CreateIoCompletionPort()函数绑定完成端口时,参数NumberOfConcurrentThreads需要设置为1。
GetQueuedCompletionStatus()用来反馈完成端口队列的状态,根据返回值,可以获得需要执行的操作。本发明中,需要实现非阻塞模式,因此在调用GetQueuedCompletionStatus()时,需要将参数dwMilliseconds设置为0,使得GetQueuedCompletionStatus()立即返回值,防止阻塞。
WSAIoctl()控制一个套接口的模式,调用成功后,WSAIoctl()函数返回0;否则的话,将返回SOCKET_ERROR错误,本发明利用WSAIoctl()取得用于完成端口的accept_ex函数指针。
本发明提供了一种Windows平台下实现单进程单线程完成端口的方法,包括以下步骤:
S1:创建一个完成端口,线程数设为1;
S2:服务端创建一个socket;
S3:将创建的socket与创建的完成端口绑定,绑定时,线程数设为1;
S4:取得用于完成端口的accept_ex函数指针;
S5:投递accept_ex操作事件到完成端口的队列中;
S6:循环调用GetQueuedCompletionStatus()函数,每次调用采用即时返回的非阻塞模式。
优选地:
步骤S1中,使用CreateIoCompletionPort()函数创建完成端口,将CreateIoCompletionPort()函数中的参数NumberOfConcurrentThreads设置为1;
步骤S3中,使用CreateIoCompletionPort()函数将创建的socket与创建的完成端口绑定,且将CreateIoCompletionPort()函数中的参数NumberOfConcurrentThreads设置为1。
优选地,步骤S6中,通过将GetQueuedCompletionStatus()函数中的参数dwMilliseconds设置为0,实现即时返回的非阻塞模式。
优选地,在步骤S6中,每次调用GetQueuedCompletionStatus()函数后,还进行如下步骤S7操作:
根据GetQueuedCompletionStatus()函数的返回值的不同,进行对应于返回值的数据处理。
优选地,当GetQueuedCompletionStatus()函数的参数lpCompletionKey返回值为ACCEPT_POST操作事件时,执行如下操作:
使用CreateIoCompletionPort()函数进行socket与完成端口的绑定,并且将参数NumberOfConcurrentThreads设置为1;
投递accept_ex操作事件和WSARecv操作事件到完成端口的队列中;
所述ACCEPT_POST操作事件为自定义的事件类型,用于表明客户端已经连接成功。
优选地,步骤S7中,当GetQueuedCompletionStatus()函数的参数lpOverlapped返回值为RECV_POST操作事件时,执行如下操作:
处理客户端发送的数据,投递WSARecv操作事件到完成端口的队列中;
处理客户端发送的数据时,若服务端需要发送数据,投递WSASend操作事件到完成端口的队列中。
优选地,步骤S7中,当GetQueuedCompletionStatus()函数的lpOverlapped返回值为SEND_POST操作事件时,执行如下操作:
投递WSASend操作事件到完成端口的队列中;
优选地,步骤S7中,当GetQueuedCompletionStatus()函数的参数lpCompletionKey返回值为CLOSE_POST时,执行如下操作:
退出步骤S6的循环,结束进程。
优选地,服务端使用socket()函数创建socket。
优选地,步骤S4中,使用WSAIoctl()函数取得类型为LPFN_ACCEPTEX的用于完成端口的accept_ex函数指针。
与现有技术相对比,本发明的有益效果如下:
1.本发明适配了一种应用场景,通过使用将完成端口与服务端socket绑定,设置线程数为1,且为非阻塞模式,实现了单进程单线程完成端口,通信逻辑处理更简单。
附图说明
图1是本发明Windows平台下实现单进程单线程完成端口的方法实施例1的流程图。
具体实施方式
下面结合附图1,对本发明的具体实施方式作详细的说明。
本发明提供了一种Windows平台下实现单进程单线程完成端口的方法,包括以下步骤:
S1:创建一个完成端口,线程数设为1;
采用CreateIoCompletionPort()函数来创建完成端口,函数定义如下:
其中,参数NumberOfConcurrentThreads表示当前运行的线程数,本发明要实现单进程单线程完成端口,因此此处创建完成端口时,需将CreateIoCompletionPort()函数中的参数NumberOfConcurrentThreads设为1。
S2:服务端创建一个socket;
服务端可以使用socket()函数创建socket,创建后服务端进行socket监听。socket()函数定义如下:
socket()函数通常用于创建一个与指定传送服务提供者捆绑的套接口,此处用socket()函数创建socket,用于下一步与完成端口的绑定。
S3:将创建的socket与创建的完成端口绑定,绑定时,线程数设为1;
为实现单进程单线程完成端口,需要将创建的socket与完成端口进行绑定,同时,因为是单线程,需要将线程数设为1。
S4:取得用于完成端口的accept_ex函数指针;
accept_ex函数用来接收客户端接入,相应客户端,支持完成端口操作,用于下一步等待接收客户端的访问数据。
S5:投递accept_ex操作事件到完成端口的队列中;
将accept_ex操作事件投递到完成端口的队列中,accept_ex操作会由内核分配执行,等待客户端的接入。
S6:循环调用GetQueuedCompletionStatus()函数,每次调用采用即时返回的非阻塞模式。
GetQueuedCompletionStatus()用来反馈完成端口队列的状态,根据返回值,可以获得需要执行的操作。GetQueuedCompletionStatus()函数定义如下:
本发明中,需要实现非阻塞模式,因此在调用GetQueuedCompletionStatus()函数时,需要进行相应设置,使得GetQueuedCompletionStatus()函数立即返回值,防止阻塞。
作为优选实施方式:
步骤S1中,使用CreateIoCompletionPort()函数创建完成端口,将CreateIoCompletionPort()函数中的参数NumberOfConcurrentThreads设置为1;
步骤S3中,使用CreateIoCompletionPort()函数将创建的socket与创建的完成端口绑定,且将CreateIoCompletionPort()函数中的参数NumberOfConcurrentThreads设置为1。
CreateIoCompletionPort()函数用来创建完成端口,参数NumberOfConcurrentThreads,表示当前运行的线程数。本发明要实现单进程单线程,因此,不但在创建完成端口时,需要将参数NumberOfConcurrentThreads需要设置为1,在使用CreateIoCompletionPort()函数绑定完成端口时,参数NumberOfConcurrentThreads也需要设置为1。
作为优选实施方式,步骤S6中,通过将GetQueuedCompletionStatus()函数中的参数dwMilliseconds设置为0,实现即时返回的非阻塞模式。
作为优选实施方式,在步骤S6中,每次调用GetQueuedCompletionStatus()函数后,还进行如下步骤S7操作:
根据GetQueuedCompletionStatus()函数的返回值的不同,进行对应于返回值的数据处理。
GetQueuedCompletionStatus()的返回值包括很多内容,比如多少字节的长度,overlapped信息,绑定的socket信息等等,根据返回的socket相关信息,进行对应于该socket相关信息的数据处理。此处返回的socket相关信息包括:事件类型。
作为优选实施方式,当GetQueuedCompletionStatus()函数的参数lpCompletionKey返回值为ACCEPT_POST操作事件时,执行如下操作:
使用CreateIoCompletionPort()函数进行socket与完成端口的绑定,并且将参数NumberOfConcurrentThreads设置为1;
投递accept_ex操作事件和WSARecv操作事件到完成端口的队列中;
所述ACCEPT_POST操作事件为自定义的事件类型,用于表明客户端已经连接成功。
GetQueuedCompletionStatus()函数返回值是BOOL型,GetQueuedCompletionStatus()有5个参数,其中下面的三个参数是可以拥有返回值的参数:
LPDWORD lpNumberOfBytes、PULONG_PTR lpCompletionKey、LPOVERLAPPED*lpOverlapped;
ACCEPT_POST为本发明自定义的事件类型,表示接收到了客户端连接,当GetQueuedCompletionStatus()的lpCompletionKey返回值为ACCEPT_POST时,则表示GetQueuedCompletionStatus()的输出参数中已经准备好了客户端连接上来的socket描述符,只需要使用CreateIoCompletionPort进行绑定即可,此时,同样需要将参数NumberOfConcurrentThreads设置为1,即线程数为1;此外需要再次投递accept_ex操作事件,等待客户端的下一次接入,以及投递WSARecv操作,用于接收客户端发送的数据。
作为优选实施方式,步骤S7中,当GetQueuedCompletionStatus()函数的参数lpOverlapped返回值为RECV_POST操作事件时,执行如下操作:
处理客户端发送的数据,投递WSARecv操作事件到完成端口的队列中;
处理客户端发送的数据时,若服务端需要发送数据,投递WSASend操作事件到完成端口的队列中。
在GetQueuedCompletionStatus()的lpOverlapped返回值中自定义参数用于返回事件类型,如自定义op_code,当GetQueuedCompletionStatus()的lpOverlapped的返回值中自定义参数如op_code为RECV_POST操作时,表示GetQueuedCompletionStatus()的输出参数中已经有客户端发送的数据到来以及收到的数据长度,此时只需要处理该数据即可,再次投递WSARecv操作,用于继续接收客户端发送的数据,当服务端需要发送数据,还需要投递WSASend操作事件到完成端口的队列中,用于发送数据。
作为优选实施方式,步骤S7中,当GetQueuedCompletionStatus()函数的lpOverlapped返回值为SEND_POST操作事件时,执行如下操作:
投递WSASend操作事件到完成端口的队列中;
在GetQueuedCompletionStatus()的lpOverlapped返回值中自定义参数用于返回事件类型,如自定义op_code,当GetQueuedCompletionStatus()的lpOverlapped的返回值的自定义参数如op_code为SEND_POST操作时,表示已经发送了数据,如果还没有发送完成,需要投递WSASend操作事件到完成端口的队列中,继续发送数据。
作为优选实施方式,步骤S7中,当GetQueuedCompletionStatus()函数的参数lpCompletionKey返回值为CLOSE_POST时,执行如下操作:
退出步骤S6的循环,结束进程。
作为优选实施方式,服务端使用socket()函数创建socket。
作为优选实施方式,步骤S4中,使用WSAIoctl()函数取得类型为LPFN_ACCEPTEX的用于完成端口的accept_ex函数指针。
WSAIoctl()控制一个套接口的模式,定义如下:
调用成功后,WSAIoctl()函数返回0;否则的话,将返回SOCKET_ERROR错误。本发明利用WSAIoctl()取得用于完成端口的accept_ex函数指针。通过WSAIoctl()获取accept_ex函数指针时,需要传递给WSAIoctl()一个有效的SOCKET,该Socket的类型不会影响获取的accept_ex函数指针。本发明利用WSAIoctl()取得类型为LPFN_ACCEPTEX的用于完成端口的accept_ex函数指针。LPFN_ACCEPTEX类型,表示:
使用方法:
实施例1
参照附图1,根据本发明的一个具体实施方案,对本发明提供的Windows平台下实现单进程单线程完成端口的方法进行详细说明。
本发明提供了一种Windows平台下实现单进程单线程完成端口的方法,包括以下步骤:
S1:创建一个完成端口,线程数设为1;
采用CreateIoCompletionPort()函数来创建完成端口,函数定义如下:
其中,参数NumberOfConcurrentThreads表示当前运行的线程数,本发明要实现单进程单线程完成端口,因此此处创建完成端口时,需将CreateIoCompletionPort()函数中的参数NumberOfConcurrentThreads设为1。
S2:服务端创建一个socket;
socket()函数通常用于创建一个与指定传送服务提供者捆绑的套接口,此处用socket()函数创建socket,用于下一步与完成端口的绑定。
S3:将创建的socket与创建的完成端口绑定,绑定时,线程数设为1;
为实现单进程单线程完成端口,需要将创建的socket与完成端口进行绑定,同时,因为是单线程,需要将线程数设为1。
步骤S3中,使用CreateIoCompletionPort()函数将创建的socket与创建的完成端口绑定,且将CreateIoCompletionPort()函数中的参数NumberOfConcurrentThreads设置为1。
CreateIoCompletionPort()函数用来创建完成端口,参数NumberOfConcurrentThreads,表示当前运行的线程数。本发明要实现单进程单线程,因此,不但在创建完成端口时,需要将参数NumberOfConcurrentThreads需要设置为1,在使用CreateIoCompletionPort()函数绑定完成端口时,参数NumberOfConcurrentThreads也需要设置为1。
S4:取得用于完成端口的accept_ex函数指针;
accept_ex函数用来接收客户端接入,相应客户端,支持完成端口操作,用于下一步等待接收客户端的访问数据。
步骤S4中,使用WSAIoctl()函数取得类型为LPFN_ACCEPTEX的用于完成端口的accept_ex函数指针。
WSAIoctl()控制一个套接口的模式,定义如下:
调用成功后,WSAIoctl()函数返回0;否则的话,将返回SOCKET_ERROR错误。本发明利用WSAIoctl()取得用于完成端口的accept_ex函数指针。通过WSAIoctl()获取accept_ex函数指针时,需要传递给WSAIoctl()一个有效的SOCKET,该Socket的类型不会影响获取的accept_ex函数指针。本发明利用WSAIoctl()取得类型为LPFN_ACCEPTEX的用于完成端口的accept_ex函数指针。
S5:投递accept_ex操作事件到完成端口的队列中;
将accept_ex操作事件投递到完成端口的队列中,accept_ex操作会由内核分配执行,等待客户端的接入。
S6:循环调用GetQueuedCompletionStatus()函数,每次调用采用即时返回的非阻塞模式。
GetQueuedCompletionStatus()用来反馈完成端口队列的状态,根据返回值,可以获得需要执行的操作。GetQueuedCompletionStatus()函数定义如下:
本发明中,需要实现非阻塞模式,因此在调用GetQueuedCompletionStatus()时,需要进行相应设置,使得GetQueuedCompletionStatus()立即返回值,防止阻塞。
步骤S6中,通过将GetQueuedCompletionStatus()函数中的参数dwMilliseconds设置为0,实现即时返回的非阻塞模式。
在步骤S6中,每次调用GetQueuedCompletionStatus()函数后,还进行如下步骤S7操作:
根据GetQueuedCompletionStatus()函数的返回值的不同,进行对应于返回值的数据处理。
GetQueuedCompletionStatus()的返回值包括很多内容,比如多少字节的长度,overlapped信息,绑定的socket信息等等,根据返回的socket相关信息,进行对应于该socket相关信息的数据处理。此处返回的socket相关信息包括:事件类型。
当GetQueuedCompletionStatus()函数的参数lpCompletionKey返回值为ACCEPT_POST操作事件时,执行如下操作:
使用CreateIoCompletionPort()函数进行socket与完成端口的绑定,并且将参数NumberOfConcurrentThreads设置为1;
投递accept_ex操作事件和WSARecv操作事件到完成端口的队列中;
ACCEPT_POST为本发明自定义的事件类型,表示有客端连接到了服务端,当GetQueuedCompletionStatus()的lpCompletionKey返回值为ACCEPT_POST时,则表示GetQueuedCompletionStatus()的输出参数中已经准备好了客户端连接上来的socket描述符,只需要使用CreateIoCompletionPort进行绑定即可,此时,同样需要将参数NumberOfConcurrentThreads设置为1,即线程数为1;此外需要再次投递accept_ex操作事件,等待客户端的下一次接入,以及投递WSARecv操作,用于接收客户端发送的数据。
步骤S7中,当GetQueuedCompletionStatus()的lpOverlapped返回值为RECV_POST操作事件时,执行如下操作:
处理客户端发送的数据,投递WSARecv操作事件到完成端口的队列中;
处理客户端发送的数据时,若服务端需要发送数据,投递WSASend操作事件到完成端口的队列中。
在GetQueuedCompletionStatus()的lpOverlapped返回值中自定义参数用于返回事件类型,如自定义op_code,当GetQueuedCompletionStatus()的lpOverlapped返回值op_code为RECV_POST操作时,表示GetQueuedCompletionStatus()的输出参数中已经有客户端发送的数据到来以及收到的数据长度,此时只需要处理该数据即可,再次投递WSARecv操作,用于继续接收客户端发送的数据,当服务端需要发送数据,还需要投递WSASend操作事件到完成端口的队列中,用于发送数据。
步骤S7中,当GetQueuedCompletionStatus()的lpOverlapped返回值为SEND_POST操作时,执行如下操作:
投递WSASend操作事件到完成端口的队列中;
在GetQueuedCompletionStatus()的lpOverlapped返回值中自定义参数用于返回事件类型,如自定义op_code,当GetQueuedCompletionStatus()的lpOverlapped返回值op_code为SEND_POST操作事件时,表示已经发送了数据,如果还没有发送完成,需要投递WSASend操作事件到完成端口的队列中,继续发送数据。
步骤S7中,当GetQueuedCompletionStatus()函数的参数lpCompletionKey返回值为CLOSE_POST时,执行如下操作:
退出步骤S6的循环,结束进程。
以上所述仅为本发明的优选实施例而已,并不用于限制本发明,对于本领域的技术人员来说,本发明可以有各种更改和变化。凡在本发明的精神和原则之内,所作的任何修改、等同替换、改进等,均包含在本发明的保护范围之内。
Claims (7)
1.一种Windows平台下实现单进程单线程完成端口的方法,其特征在于,包括以下步骤:
S1:创建一个完成端口,线程数设为1;
S2:服务端创建一个socket;
S3:将创建的socket与创建的完成端口绑定,绑定时,线程数设为1;
S4:取得用于完成端口的accept_ex函数指针;
S5:投递accept_ex操作事件到完成端口的队列中;
S6:循环调用GetQueuedCompletionStatus()函数,每次调用采用即时返回的非阻塞模式;
步骤S6中,通过将GetQueuedCompletionStatus()函数中的参数dwMilliseconds设置为0,实现即时返回的非阻塞模式;
S7:根据GetQueuedCompletionStatus()函数的返回值的不同,进行对应于返回值的数据处理;
其中,步骤S7中判断的GetQueuedCompletionStatus()函数的所述返回值包括:GetQueuedCompletionStatus()函数中参数lpCompletionKey的返回值和GetQueuedCompletionStatus()函数中参数lpOverlapped的返回值,其中在lpOverlapped的返回值中自定义参数用于返回事件类型;
当GetQueuedCompletionStatus()函数的参数lpOverlapped返回值为RECV_POST操作事件时,执行如下操作:
处理客户端发送的数据,投递WSARecv操作事件到完成端口的队列中;
处理客户端发送的数据时,若服务端需要发送数据,投递WSASend操作事件到完成端口的队列中。
2.根据权利要求1所述的实现单进程单线程完成端口的方法,其特征在于:
步骤S1中,使用CreateIoCompletionPort()函数创建完成端口,将CreateIoCompletionPort()函数中的参数NumberOfConcurrentThreads设置为1;
步骤S3中,使用CreateIoCompletionPort()函数将创建的socket与创建的完成端口绑定,且将CreateIoCompletionPort()函数中的参数NumberOfConcurrentThreads设置为1。
3.根据权利要求1所述的实现单进程单线程完成端口的方法,其特征在于,当GetQueuedCompletionStatus()函数的参数lpCompletionKey返回值为ACCEPT_POST操作事件时,执行如下操作:
使用CreateIoCompletionPort()函数进行socket与完成端口的绑定,并且将参数NumberOfConcurrentThreads设置为1;
投递accept_ex操作事件和WSARecv操作事件到完成端口的队列中;
所述ACCEPT_POST操作事件为自定义的事件类型,用于表明客户端已经连接成功。
4.根据权利要求1所述的实现单进程单线程完成端口的方法,其特征在于,步骤S7中,当GetQueuedCompletionStatus()函数的lpOverlapped返回值为SEND_POST操作事件时,执行如下操作:
投递WSASend操作事件到完成端口的队列中。
5.根据权利要求1所述的实现单进程单线程完成端口的方法,其特征在于,步骤S7中,当GetQueuedCompletionStatus()函数的参数lpCompletionKey返回值为CLOSE_POST时,执行如下操作:
退出步骤S6的循环,结束进程。
6.根据权利要求1所述的实现单进程单线程完成端口的方法,其特征在于,服务端使用socket()函数并创建一个socket。
7.根据权利要求1所述的实现单进程单线程完成端口的方法,其特征在于,步骤S4中,使用WSAIoctl()函数取得类型为LPFN_ACCEPTEX的用于完成端口的accept_ex函数指针。
Priority Applications (1)
Application Number | Priority Date | Filing Date | Title |
---|---|---|---|
CN202011038746.3A CN112114955B (zh) | 2020-09-28 | 2020-09-28 | Windows平台下实现单进程单线程完成端口的方法 |
Applications Claiming Priority (1)
Application Number | Priority Date | Filing Date | Title |
---|---|---|---|
CN202011038746.3A CN112114955B (zh) | 2020-09-28 | 2020-09-28 | Windows平台下实现单进程单线程完成端口的方法 |
Publications (2)
Publication Number | Publication Date |
---|---|
CN112114955A CN112114955A (zh) | 2020-12-22 |
CN112114955B true CN112114955B (zh) | 2021-05-14 |
Family
ID=73798251
Family Applications (1)
Application Number | Title | Priority Date | Filing Date |
---|---|---|---|
CN202011038746.3A Active CN112114955B (zh) | 2020-09-28 | 2020-09-28 | Windows平台下实现单进程单线程完成端口的方法 |
Country Status (1)
Country | Link |
---|---|
CN (1) | CN112114955B (zh) |
Families Citing this family (1)
Publication number | Priority date | Publication date | Assignee | Title |
---|---|---|---|---|
CN113032118A (zh) * | 2021-03-22 | 2021-06-25 | 北京元年科技股份有限公司 | 用于计算机应用程序的异步操作处理方法和相应的系统 |
Family Cites Families (12)
Publication number | Priority date | Publication date | Assignee | Title |
---|---|---|---|---|
US20030117959A1 (en) * | 2001-12-10 | 2003-06-26 | Igor Taranov | Methods and apparatus for placement of test packets onto a data communication network |
US8943181B2 (en) * | 2005-11-29 | 2015-01-27 | Ebay Inc. | Method and system for reducing connections to a database |
US8390631B2 (en) * | 2008-06-11 | 2013-03-05 | Microsoft Corporation | Synchronizing queued data access between multiple GPU rendering contexts |
CN102103676B (zh) * | 2011-02-28 | 2013-09-25 | 南京邮电大学 | 一种基于进程间继承关系的爪哇程序进程守护方法 |
CN103391289A (zh) * | 2013-07-16 | 2013-11-13 | 中船重工(武汉)凌久高科有限公司 | 一种基于完成端口模型的多链路安全通信方法 |
CN103634324B (zh) * | 2013-12-09 | 2017-10-31 | 飞天诚信科技股份有限公司 | 一种实时监控证书的方法 |
CN108270732B (zh) * | 2016-12-30 | 2019-02-19 | 视联动力信息技术股份有限公司 | 一种流媒体处理方法及系统 |
CN108376098A (zh) * | 2017-02-01 | 2018-08-07 | 长沙青核桃网络科技有限公司 | 一种应用于Windows下完成端口模型操作系统 |
CN107526645B (zh) * | 2017-09-06 | 2019-01-29 | 武汉斗鱼网络科技有限公司 | 一种通信优化方法及系统 |
WO2019056203A1 (zh) * | 2017-09-20 | 2019-03-28 | 深圳市海能通信股份有限公司 | 一种低延时音视频传输方法、装置及计算机可读存储介质 |
CN109660569B (zh) * | 2017-10-10 | 2021-10-15 | 武汉斗鱼网络科技有限公司 | 一种多任务并发执行方法、存储介质、设备及系统 |
CN109302646A (zh) * | 2018-11-22 | 2019-02-01 | 安徽翼迈科技股份有限公司 | 一种基于gprs的水表远程抄表系统和系统的实现方法 |
-
2020
- 2020-09-28 CN CN202011038746.3A patent/CN112114955B/zh active Active
Also Published As
Publication number | Publication date |
---|---|
CN112114955A (zh) | 2020-12-22 |
Similar Documents
Publication | Publication Date | Title |
---|---|---|
US7272834B2 (en) | Method for continuous I/O request processing in an asynchronous environment | |
JP3691515B2 (ja) | オペレーティングシステムにおけるイベント分配装置及び方法 | |
CN106161537B (zh) | 远程过程调用的处理方法、装置、系统及电子设备 | |
US8635388B2 (en) | Method and system for an OS virtualization-aware network interface card | |
WO2014187412A1 (zh) | 消息处理线程的控制方法及装置 | |
US6421701B1 (en) | Method and system for replication support in a remote method invocation system | |
US9544261B2 (en) | Data communications in a distributed computing environment | |
CN101882089A (zh) | 一种采用多线程处理业务会话应用的方法及装置 | |
CN110795254A (zh) | 一种基于php处理高并发io的方法 | |
WO2018077284A1 (zh) | 通信方法和系统、电子设备和计算机集群 | |
EP0561042B1 (en) | Dual process display server | |
US20150195229A1 (en) | Listening for externally initiated requests | |
CN102904961A (zh) | 一种云计算资源调度方法及系统 | |
CN109542642A (zh) | 一种前端任务处理的方法及装置 | |
CN112114955B (zh) | Windows平台下实现单进程单线程完成端口的方法 | |
WO2020156797A1 (en) | Handling an input/output store instruction | |
CN113703997A (zh) | 集成多种消息代理的双向异步通信中间件系统及实现方法 | |
CN111282263A (zh) | 事件消息的处理方法、装置、电子设备及可读存储介质 | |
US10673983B2 (en) | Processing a unit of work | |
US20050198127A1 (en) | Systems and methods that facilitate in-order serial processing of related messages | |
US20020083211A1 (en) | Method and apparatus for synchronizing calls in a server and client system | |
CN113965628A (zh) | 消息调度方法、服务器和存储介质 | |
CN106911739B (zh) | 一种信息分发方法及装置 | |
CN115361382A (zh) | 基于数据群组的数据处理方法、装置、设备和存储介质 | |
US20140019992A1 (en) | Method of Parallel Processing of Ordered Data Streams |
Legal Events
Date | Code | Title | Description |
---|---|---|---|
PB01 | Publication | ||
PB01 | Publication | ||
SE01 | Entry into force of request for substantive examination | ||
SE01 | Entry into force of request for substantive examination | ||
GR01 | Patent grant | ||
GR01 | Patent grant |