IOCP

合集下载

名词解释IOCP简介四-Read

名词解释IOCP简介四-Read

hIOCP = CreateIoCompletionPort(INVALID_HANDLE_VALUE, NULL, 0, 0);
该语句的作用是返回一个句柄,在为完成端口分配了一个套接字句柄后,用来对那个 端口进行标定(引用)。
函数功能:注意该函数实际用于两个明显有别的目的: 1. 用于创建一个完成端口对象。 2. 将一个句柄同完成端口关联到一起。
IOCP简介

IOCP的开发
1、CreateIoCompletionPort
最开始创建一个完成端口时,唯一感兴趣的参数便是 NumberOfConcurrentThreads(并发线程的数量);前面三个参数都会被忽略。 NumberOfConcurrentThreads参数的特殊之处在于,它定义了在一个完成端口上, 同时允许执行的线程数量。理想情况下,我们希望每个处理器各自负责一个线程的运 行,为完成端口提供服务,避免过于频繁的线程“场景”切换。若将该参数设为0Байду номын сангаас 表明系统内安装了多少个处理器,便允许同时运行多少个线程!可用下述代码创建一 个I/O完成端口:
IOCP简介

IOCP的应用
可以看出完成端口是到目前为止最为复杂的输入输出模式。然而,当一个 应用不得不同时处理大量的socket时,它也提供了使系统性能达到最佳的可 能性。只有在被迫面对几百甚至几千个并发的socket、你又希望在添加CPU 后可以获得更好的scale时,才被派上战场。关于完成端口,最重要的是记住 这一点:如果你为winnt/2000开发处理大量socket I/O 请求的高性能服 务,它是你的最佳选择 IOCP不仅仅在通信socket上,同时也可以用于其他方面,例如读写文件, 比如把文件句柄关联到完成端口上,产生一定量的工作器线程,读取文件不同 的部分实际读取数据是系统内部处理,只是读取完了通知一下,并且把相关I O数据填充到结构体中

IOCP模型总结

IOCP模型总结

IOCP模型总结IOCP模型基于Windows操作系统的异步I/O机制,利用操作系统提供的I/O完成端口来管理I/O操作。

在IOCP模型中,主线程将I/O操作的控制权交给I/O线程池去完成,从而提高了系统的并发处理能力。

当I/O操作完成后,操作系统会通知应用程序将已经完成的I/O操作从I/O 完成端口中取出并进行处理。

1.高性能:IOCP模型使用异步I/O的方式,避免了传统的同步I/O 中频繁的等待和轮询操作,从而减少了CPU的资源消耗。

2.可扩展性:IOCP模型利用了线程池来管理I/O操作,通过配置线程池的线程个数可以调整系统的扩展性,适应高负载的场景。

3.可靠性:IOCP模型在设计上考虑了请求处理的完整性,异步I/O 操作与应用程序的逻辑分离,保证了I/O操作的可靠性。

4. 多协议支持:IOCP模型不仅支持TCP和UDP协议,还支持其他的网络协议,如IPX/SPX、NetBEUI等。

1.高并发处理能力:IOCP模型通过使用异步I/O和I/O线程池,可以高效地处理大量的并发请求,提高了系统的并发处理能力。

2.低系统开销:IOCP模型避免了传统同步I/O模型中的频繁的等待和轮询操作,减少了系统开销,提高了系统的性能。

3.灵活的扩展性:IOCP模型使用线程池来管理I/O操作,通过调整线程池的大小可以灵活地扩展系统的能力,适应不同的负载需求。

4.容易实现和使用:IOCP模型提供了简单的API接口,易于实现和使用,不需要过多的底层细节和复杂的编程逻辑。

1.网络服务器:IOCP模型在网络服务器中具有广泛的应用,可以高效地处理大规模的并发网络请求,提高服务器的性能和吞吐量。

2.实时数据处理:IOCP模型适用于需要实时处理大量数据的场景,如实时数据采集、实时广播、实时监控等。

3.高性能计算:IOCP模型在需要高性能计算的场景中也有应用,如科学计算、金融分析、图像处理等。

总结:IOCP模型是一种高效的I/O模型,在Windows系统中具有重要的地位和广泛的应用。

IOCP模型总结

IOCP模型总结

IOCP模型总结
IOCP模型的基本原理是使用操作系统提供的一个输入/输出完成端口,服务器在等待I/O完成时可以继续处理其他的请求(非阻塞),当操作系
统I/O操作完成之后,会通过回调函数的方式通知服务器,从而让服务器
能够及时处理已完成的请求。

2. 创建工作线程(CreateThread):服务器需要创建一定数量的工
作线程,用于处理来自客户端的请求和处理完成端口的通知。

这些工作线
程会在每一个请求到来时进行处理,当有I/O操作完成时,通过回调函数
的方式通知工作线程进行处理。

1.高吞吐量:通过多线程异步I/O的方式,充分利用了硬件性能和操
作系统的特性,能够处理大量的并发请求,提高服务器的吞吐量。

2.高性能:由于保持了非阻塞状态,减少了线程的阻塞时间,服务器
能够更快地响应请求,提供更好的性能。

3.可扩展性好:通过使用多线程模型,服务器可以根据需要动态调整
工作线程的数量,以适应不同的负载情况。

4.高并发处理能力:IOCP模型使用操作系统的通知机制,可以同时
处理多个I/O请求,大大提高了服务器的并发处理能力。

5.方便管理和维护:IOCP模型对服务器的管理和维护提供了便利,
通过将I/O完成的通知传递给操作系统,不需要服务器自己去维护和管理
线程,也无需关心线程的创建和销毁等问题。

总之,IOCP模型是一种高性能、高并发的I/O处理模式,通过利用
操作系统的特性和硬件性能,提高了服务器的处理能力。

它广泛应用于网
络服务器、数据库服务器等需要处理并发请求的场景,能够为用户提供更快速、更稳定的服务。

iocp 编程

iocp 编程

IOCP编程什么是IOCPIOCP(Input/Output Completion Ports)是一种高效的异步I/O模型,它在Windows操作系统中提供了对网络编程的支持。

通过使用IOCP,我们可以实现高性能、可伸缩性强的网络应用程序。

在传统的同步I/O模型中,当一个线程在等待数据时,它会被阻塞,直到数据到达。

而在异步I/O模型中,线程不会被阻塞,它可以继续执行其他任务。

IOCP就是基于这种异步I/O模型实现的。

IOCP的工作原理使用IOCP进行编程主要涉及以下几个核心概念:端口(Port)、完成包(Completion Packet)、套接字(Socket)和重叠操作(Overlapped Operation)。

•端口:一个端口代表一个I/O设备或者一个文件。

每个端口都有一个关联的完成端口。

•完成包:完成包是指一个I/O操作完成时所生成的信息块。

它包含了完成的状态、相关参数和返回值等信息。

•套接字:套接字是网络编程中用于进行通信的抽象概念。

•重叠操作:重叠操作是指一次I/O操作请求,在请求发出之后,线程就可以继续执行其他任务了。

IOCP主要通过以下几个步骤来实现异步I/O:1.创建一个完成端口(Completion Port)。

2.创建一个或多个工作者线程(Worker Thread),这些线程用于处理I/O操作。

3.将套接字关联到完成端口上,使得该套接字上的I/O操作能够被异步处理。

4.当有I/O操作完成时,系统会将相关的完成包放入完成队列中。

5.工作者线程从完成队列中获取完成包,并进行相应的处理。

IOCP的优势和适用场景相比于传统的同步阻塞模型,IOCP具有以下几个优势:1.高性能:IOCP能够充分利用CPU资源,提高程序的并发处理能力。

它通过异步I/O模型,使得线程在等待数据时不被阻塞,可以继续执行其他任务,从而充分利用了CPU资源。

2.可伸缩性:IOCP可以轻松地扩展到支持大量的并发连接。

简述iocp模型的原理和工作过程

简述iocp模型的原理和工作过程

简述iocp模型的原理和工作过程IOCP模型的原理和工作过程如下:原理:IOCP模型的核心原理是利用操作系统提供的异步I/O和内核级事件通知机制。

异步I/O使得应用程序可以在等待I/O完成时继续处理其他任务,而内核级事件通知机制可以使得操作系统在I/O完成后主动通知应用程序。

通过将I/O操作的处理放在操作系统层面,IOCP模型能够实现高并发、高吞吐量的网络通信。

工作过程:1.创建IOCP对象:应用程序首先创建一个IOCP对象,用于和操作系统进行通信。

2.绑定套接字:应用程序将要进行异步I/O操作的套接字与IOCP对象进行关联。

3.接受连接:应用程序使用套接字进行监听,并且接受到客户端连接请求后,将连接套接字与IOCP对象进行关联,从而使得这个连接套接字能够参与IOCP模型的异步I/O操作。

4.发送和接收数据:应用程序通过调用操作系统提供的异步I/O操作函数,发起网络数据的发送和接收操作。

在发送和接收操作完成之前,应用程序可以继续处理其他任务。

5.等待通知:在发送和接收操作完成之后,应用程序会调用一个等待通知的函数,将自己挂起,等待操作系统的通知。

6.I/O完成通知:当操作系统中发生I/O操作完成的事件时,IOCP对象会通知应用程序,并将I/O操作的结果返回给应用程序。

7.处理完成的I/O操作:应用程序在收到I/O完成的通知后,可以根据返回的结果进行相应的处理。

通常会将I/O操作的结果放入一个队列中,以便后续的处理。

8.处理队列中的完成操作:应用程序会不断地从队列中取出已完成的I/O操作,并进行相应的处理。

处理完成的操作后,应用程序可以继续发起新的I/O操作,从而实现不断地进行网络通信。

总结:IOCP模型利用操作系统提供的异步I/O和内核级事件通知机制,将网络通信的I/O操作交给操作系统来处理,从而实现了高并发、高吞吐量的网络通信。

应用程序通过调用操作系统提供的异步I/O函数来发起发送和接收数据的操作,在操作完成前可以继续处理其他任务。

iocp流程

iocp流程

iocp流程I/O Completion Port (IOCP) 是 Windows 系统提供的一种高效的 I/O 模型,可以大大提高网络编程的效率和性能。

在分析 IOCP 流程之前,首先要了解 IOCP 的一些基本原理和用法。

IOCP 基本原理IOCP 的基本原理是通过 CreateIoCompletionPort 函数创建一个 I/O 完成端口句柄,将相关的操作(如异步 I/O 操作)关联到该句柄上,并通过 GetQueuedCompletionStatus 函数等待 I/O 完成事件的发生,当事件发生后,系统会自动调用已经与完成端口关联的回调函数来处理该事件。

IOCP 使用步骤下面是使用 IOCP 模型进行网络编程的基本步骤:1. 创建 I/O 完成端口句柄使用 CreateIoCompletionPort 函数创建一个 I/O 完成端口句柄,并指定线程池大小(ThreadCount),通常设置为处理器数量的两倍或三倍,具体根据实际情况进行调整,以提高并发处理能力。

2. 创建套接字并绑定到 I/O 完成端口使用 socket 函数创建一个网络套接字,并将其绑定到 I/O 完成端口句柄上,以便在套接字上的 I/O 操作完成时能够自动通知 I/O 完成端口。

3. 提交 I/O 操作使用 WSARecv 和 WSASend 等函数提交 I/O 操作,将 I/O 操作相关的参数(如套接字句柄、缓冲区、长度等)传递给函数,函数会马上返回,操作会在后台异步执行。

4. 获取 I/O 完成事件使用 GetQueuedCompletionStatus 函数从 I/O 完成端口句柄上获取I/O 完成事件,并将相关的参数(如套接字句柄、缓冲区、长度等)传递给回调函数,回调函数会根据事件类型进行相应的处理(如接收数据或发送数据)。

5. 处理 I/O 完成事件在回调函数中,根据写操作或是读操作的不同,调用相应的函数(如WSASend 或 WSARecv)处理 I/O 完成事件,并提交下一轮 I/O 操作,以便继续异步执行。

iocp的udp例子

iocp的udp例子

iocp的udp例子首先,我们需要了解什么是IOCP(Input/Output Completion Port)以及它在网络编程中的作用。

IOCP是Windows系统提供的一种高性能的I/O模型,它能够通过异步的方式处理大量的I/O操作,包括网络通信。

通过IOCP,我们可以提高网络应用程序的并发性能和可扩展性。

在网络编程中,UDP(User Datagram Protocol)是一种无连接、不可靠的传输协议,它可以在网络上以较低的延迟发送数据包。

相比于TCP协议,UDP协议更适合传输实时性较高的数据,如音视频等。

现在,我们将结合上述两个概念,通过一个简单的UDP例子来说明如何利用IOCP实现高性能网络通信。

请注意,以下是一个基本的框架,并非可运行的完整代码。

首先,我们需要创建一个IOCP对象。

在Windows系统中,可以通过调用CreateIoCompletionPort函数来实现:c++HANDLE completionPort =CreateIoCompletionPort(INVALID_HANDLE_VALUE, NULL, 0, 0);接下来,我们需要创建一个UDP套接字,并将其绑定到指定的IP地址和端口上。

通过调用bind函数来实现:c++SOCKET udpSocket = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP);sockaddr_in serverAddress;serverAddress.sin_family = AF_INET;serverAddress.sin_addr.s_addr = htonl(INADDR_ANY); serverAddress.sin_port = htons(1234);bind(udpSocket, (sockaddr*)&serverAddress,sizeof(serverAddress));然后,我们需要将该UDP套接字与IOCP对象关联起来,以便IOCP能够管理其I/O操作。

iocp的udp例子

iocp的udp例子

iocp的udp例子【原创版】目录1.IOCP 和 UDP 简介2.IOCP 的 UDP 例子:简单的 UDP 客户端和服务器3.实现步骤和代码详解4.总结正文1.IOCP 和 UDP 简介IOCP(Input/Output Completion Port)是一种 I/O 模型,主要用于 Windows 操作系统,以异步 I/O 操作为主要特点。

UDP(User Datagram Protocol)是一种无连接的传输层协议,具有传输速度快、开销小的优点。

在许多网络应用中,UDP 是一种理想的选择,因为它可以有效地传输数据,而不需要建立连接和维护状态。

2.IOCP 的 UDP 例子:简单的 UDP 客户端和服务器为了演示 IOCP 和 UDP 的结合,我们可以创建一个简单的 UDP 客户端和服务器。

服务器监听一个端口,等待客户端发送数据,并将接收到的数据原样发送回客户端。

客户端发送数据到服务器,然后接收并打印服务器返回的数据。

3.实现步骤和代码详解(1)创建 UDP 套接字首先,我们需要使用 socket 函数创建一个 UDP 套接字。

套接字分为发送和接收两个部分,分别用于发送数据和接收数据。

(2)绑定套接字接下来,我们需要将套接字与本地地址和端口绑定。

使用 bind 函数将套接字与指定的本地地址和端口绑定。

(3)创建 IOCP创建一个 IOCP 实例,用于处理网络数据。

使用CreateIoCompletionPort 函数创建一个新的 IOCP 实例,并将其与 UDP 套接字关联。

(4)设置 IOCP 事件为了处理网络数据,我们需要设置 IOCP 事件。

使用SetIoCompletionPort 函数设置 IOCP 事件,以便在数据到达或发送时得到通知。

(5)处理接收数据当接收到数据时,我们需要从套接字中读取数据,并将其发送回客户端。

使用 GetFromOverlappedResult 函数获取接收到的数据,然后使用sendto 函数将数据发送回客户端。

  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。

完成IO使用总结IOCP(I/O Completion Port,I/O完成端口)是性能最好的一种I/O模型。

它是应用程序使用线程池处理异步I/O请求的一种机制。

在处理多个并发的异步I/O请求时,以往的模型都是在接收请求是创建一个线程来应答请求。

这样就有很多的线程并行地运行在系统中。

而这些线程都是可运行的,Windows内核花费大量的时间在进行线程的上下文切换,并没有多少时间花在线程运行上。

再加上创建新线程的开销比较大,所以造成了效率的低下。

调用的步骤如下:抽象出一个完成端口大概的处理流程:1:创建一个完成端口。

2:创建一个线程A。

3:A线程循环调用GetQueuedCompletionStatus()函数来得到IO操作结果,这个函数是个阻塞函数。

4:主线程循环里调用accept等待客户端连接上来。

5:主线程里accept返回新连接建立以后,把这个新的套接字句柄用CreateIoCompletionPort 关联到完成端口,然后发出一个异步的WSASend或者WSARecv调用,因为是异步函数,WSASend/WSARecv会马上返回,实际的发送或者接收数据的操作由WINDOWS系统去做。

6:主线程继续下一次循环,阻塞在accept这里等待客户端连接。

7:WINDOWS系统完成WSASend或者WSArecv的操作,把结果发到完成端口。

8:A线程里的GetQueuedCompletionStatus()马上返回,并从完成端口取得刚完成的WSASend/WSARecv的结果。

9:在A线程里对这些数据进行处理(如果处理过程很耗时,需要新开线程处理),然后接着发出WSASend/WSARecv,并继续下一次循环阻塞在GetQueuedCompletionStatus()这里。

归根到底概括完成端口模型一句话:我们不停地发出异步的WSASend/WSARecv IO操作,具体的IO处理过程由WINDOWS系统完成,WINDOWS系统完成实际的IO处理后,把结果送到完成端口上(如果有多个IO 都完成了,那么就在完成端口那里排成一个队列)。

我们在另外一个线程里从完成端口不断地取出IO操作结果,然后根据需要再发出WSASend/WSARecv IO操作。

而IOCP模型是事先开好了N个线程,存储在线程池中,让他们hold。

然后将所有用户的请求都投递到一个完成端口上,然后N个工作线程逐一地从完成端口中取得用户消息并加以处理。

这样就避免了为每个用户开一个线程。

既减少了线程资源,又提高了线程的利用率。

完成端口模型是怎样实现的呢?我们先创建一个完成端口(::CreateIoCompletioPort())。

然后再创建一个或多个工作线程,并指定他们到这个完成端口上去读取数据。

我们再将远程连接的套接字句柄关联到这个完成端口(还是用::CreateIoCompletionPort())。

一切就OK了。

工作线程都干些什么呢?首先是调用::GetQueuedCompletionStatus()函数在关联到这个完成端口上的所有套接字上等待I/O的完成。

再判断完成了什么类型的I/O。

一般来说,有三种类型的I/O,OP_ACCEPT,OP_READ和OP_WIRTE。

我们到数据缓冲区内读取数据后,再投递一个或是多个同类型的I/O即可(::AcceptEx()、::WSARecv()、::WSASend())。

对读取到的数据,我们可以按照自己的需要来进行相应的处理。

为此,我们需要一个以OVERLAPPED(重叠I/O)结构为第一个字段的per-I/O数据自定义结构。

typedef struct _PER_IO_DA TA{OVERLAPPED ol; // 重叠I/O结构char buf[BUFFER_SIZE]; // 数据缓冲区int nOperationType; //I/O操作类型#define OP_READ 1#define OP_WRITE 2#define OP_ACCEPT 3} PER_IO_DA TA, *PPER_IO_DA TA;将一个PER_IO_DA TA结构强制转化成一个OVERLAPPED结构传给::GetQueuedCompletionStatus()函数,返回的这个PER_IO_DA TA结构的的nOperationType 就是I/O操作的类型。

当然,这些类型都是在投递I/O请求时自己设置的。

这样一个IOCP服务器的框架就出来了。

当然,要做一个好的IOCP服务器,还有考虑很多问题,如内存资源管理、接受连接的方法、恶意的客户连接、包的重排序等等。

以上是个人对于IOCP模型的一些理解与看法,还有待完善。

另外各Winsock API的用法参见MSDN。

完成端口中的单句柄数据结构与单IO数据结构的理解与设计完成端口模型,针对于win平台的其它异步网络模型而言,最大的好处,除了性能方面的卓越外,还在于完成端口在传递网络事件的通知时,可以一并传递与此事件相关的应用层数据。

这个应用层数据,体现在两个方面:一是单句柄数据,二是单io数据。

getqueuedcompletionstatus函数的原型如下:winbaseapiboolwinapigetqueuedcompletionstatus(in handle completionport,out lpdword lpnumberofbytestransferred,out pulong_ptr lpcompletionkey,out lpoverlapped *lpoverlapped,in dword dwmilliseconds);其中,我们把第三个参数lpcompletionkey称为完成键,由它传递的数据称为单句柄数据。

我们把第四个参数lpoverlapped称为重叠结构体,由它传递的数据称为单io数据。

以字面的意思来理解,lpcompletionkey内包容的东西应该是与各个socket一一对应的,而lpoverlapped是与每一次的wsarecv或wsasend操作一一对应的。

在网络模型的常见设计中,当一个客户端连接到服务器后,服务器会通过accept或acceptex创建一个socket,而应用层为了保存与此socket相关的其它信息(比如:该socket 所对应的sockaddr_in结构体数据,该结构体内含客户端ip等信息,以及为便于客户端的逻辑包整理而准备的数据整理缓冲区等),往往需要创建一个与该socket一一对应的客户端底层通信对象,这个对象可以负责保存仅在网络层需要处理的数据成员和方法,然后我们需要将此客户端底层通信对象放入一个类似于list或map的容器中,待到需要使用的时候,使用容器的查找算法根据socket值找到它所对应的对象然后进行我们所需要的操作。

让人非常高兴的是,完成端口“体贴入微”,它已经帮我们在每次的完成事件通知时,稍带着把该socket所对应的底层通信对象的指针送给了我们,这个指针就是lpcompletionkey。

也就是说,当我们从getqueuedcompletionstatus函数取得一个数据接收完成的通知,需要将此次收到的数据放到该socket所对应的通信对象整理缓冲区内对数据进行整理时,我们已经不需要去执行list或map等的查找算法,而是可以直接定位这个对象了,当客户端连接量很大时,频繁查表还是很影响效率的。

哇哦,太帅了,不是吗?呵呵。

基于以上的认识,我们的lpcompletionkey对象可以设计如下:typedef struct per_handle_data{socket socket;//本结构体对应的socket值sockaddr_in addr;//用于存放客户端ip等信息char databuf[ 2*max_buffer_size ];//整理缓冲区,用于存放每次整理时的数据}per_handle_data与socket的绑定,通过createiocompletionport完成,将该结构体地址作为该函数的第三个参数传入即可。

而per_handle_data结构体中addr成员,是在accept执行成功后进行赋值的。

databuf则可以在每次wsarecv操作完成,需要整理缓冲区数据时使用。

下面我们再来看看完成端口的收、发操作中所使用到的重叠结构体overlapped。

关于重叠io的知识,请自行google相关资料。

简单地说,overlapped是应用层与核心层交互共享的数据单元,如果要执行一个重叠io操作,必须带有overlapped结构。

在完成端口中,它允许应用层对overlapped结构进行扩展和自定义,允许应用层根据自己的需要在overlapped的基础上形成新的扩展overlapped结构。

一般地,扩展的overlapped结构中,要求放在第一个的数据成员是原overlapped结构。

我们可以形如以下方式定义自己的扩展overlapped结构:typedef struct per_io_data{overlapped ovl;wsabuf buf;char recvdatabuf[ max_buffer_size ]; //接收缓冲区char senddatabuf[ max_buffer_size ]; //发送缓冲区optype optype; //操作类型:发送、接收或关闭等}在执行wsasend和wsarecv操作时,应用层会将扩展overlapped结构的地址传给核心,核心完成相应的操作后,仍然通过原有的这个结构传递操作结果,比如“接收”操作完成后,recvdatabuf里存放便是此次接收下来的数据。

根据各自应用的不同,不同的完成端口设计者可能会设计出不同的per_handle_data和per_io_data,我这里给出的设计也只是针对自己的应用场合的,不一定就适合你。

但我想,最主要的还是要搞明白per_handle_data和per_io_data两种结构体的含义、用途,以及调用流程。

对CRITICAL_SECTION理解的总结很多人对CRITICAL_SECTION的理解是错误的,认为CRITICAL_SECTION是锁定了资源,其实,CRITICAL_SECTION是不能够“锁定”资源的,它能够完成的功能,是同步不同线程的代码段。

简单说,当一个线程执行了EnterCritialSection之后,cs里面的信息便被修改了,以指明哪一个线程占用了它。

而此时,并没有任何资源被“锁定”。

不管什么资源,其它线程都还是可以访问的(当然,执行的结果可能是错误的)。

只不过,在这个线程尚未执行LeaveCriticalSection之前,其它线程碰到EnterCritialSection语句的话,就会处于等待状态,相当于线程被挂起了。

相关文档
最新文档