怀仁网站建设,便宜点的网站空间,wordpress酒店,制作网页需要的技术LF模式是个坑#xff0c;一个小小的失误就可能使你的网络处理瘫痪#xff0c;Ice就很好地展现了出来#xff0c;换句话说#xff0c;Ice中间件或是LF模式就是一个坑#xff0c;如果你一不小心。 LF模式的官方论文中#xff0c;论述了此模式用于高性能网络并发模式#x…LF模式是个坑一个小小的失误就可能使你的网络处理瘫痪Ice就很好地展现了出来换句话说Ice中间件或是LF模式就是一个坑如果你一不小心。 LF模式的官方论文中论述了此模式用于高性能网络并发模式使用的是系统的隐式队列也就是Reactor复用多路IO如果是select的话还是会将事件收集到一个显式队列每次只有一条线程可以有一次机会成为leader访问这个队列从队列取出事件后放弃leader同时唤醒另一线程如果还有follower线程的话注意这时的线程既不是leader也不是follower它就可以处理事件一般就是同步非阻塞读写然后处理这个请求通常来说就是dispatchFromThisThread。当上面的工作结束就才会作为follower等待成为leader如果没有leader的话就会马上成为leader。在这种模式中称为LF模式有点误导因为实际上是三种状态LPFLeaderProcessFollower状态机为 L-P-F-L-...。Follower状态的线程阻塞等待着Leader离开Leader状态去Process从而唤醒可能的Follower状态的线程。被唤醒的Follower线程状态变为Leader成为线程池中唯一当前有权操作队列的线程要么阻塞在空队列要么取出队列一个事件离开Leader状态去Process。线程池线程当Process完事件后才会状态变为Follower或者阻塞等待Leader的唤醒或者自动成为Leader。状态机就为 Lblock on event queue-P-F-block on followers queue-L ...。在这种模式下的线程池中最多只有一个线程在Leader状态并且只有这个Leader线程可以阻塞在IO事件队列其它线程要么在Process状态处理事件要么就是在Follower状态等待成为下一个Leader。当没有IO事件的时候就只有一个线程在Leader状态阻塞在IO事件队列其它线程都结事了事件的处理并在Follower状态阻塞等待Leader线程释放信号。 通常用来衬托LF模式的就是sync/async模式并且都会举例Manager-Workers线程池。Manager负责将队列的事件指派到空闲Worker线程进行处理。Worker线程被唤醒处理完事件后再次阻塞等待Manager唤醒。当没有事件的时候Manager阻塞在事件队列Worker线程阻塞等待Manager线程唤醒。这种线程池有一个固定线程去阻塞在事件队列。并且每次Manager唤醒Worker都要通过堆来传递事件。Manager从事件队列取出一个事件写入到堆内存Worker从堆内存读到自己的栈然后处理栈上的这个事件而Leader从事件队列将一个事件读到自己的栈再就唤醒其它Follower然后处理栈上的这个事件。当Manager线程不负责Reactor复用多路IO的情况在空闲时发生了一次IO事件必须跨线程写入Manager线程的事件队列并唤醒Manager线程然后Manager线程唤醒Worker线程去处理事件。而LF模式线程池Leader从系统的多路IO复用分离函数中返回唤醒一个Follower然后自己去处理事件。这样一比较就是Manager-Workers线程池进行了两次线程唤醒而LF模式线程池只有一个线程唤醒这里必须要公正Leader是之前就被唤醒经历消耗了一次切换事件在Manager-Workers线程池需要多次拷贝。 那么为什么LF模式不心就会踩坑而Ice的设计就让体会这个坑。 问题在于如果LF模式线程池的线程进行Process阻塞等待IO响应而所有的线程都在Process过程中阻塞等待IO响应更重要这些被等待的IO应用在这个线程池的Reactor就会再也没有线程成为Leader去多路IO分离函数中读取IO事件。这时候这个LF线程池就会瘫痪不工作。Ice中间件会让你深深体会这种痛。Ice采用ActiveObject模式进行OBR对象代理请求。控制线程调用proxy请求返回一个future阻塞等待future。Communicator的clientThreadPool负责Reactor收到请求的response后就向future发信号从而唤醒这个response对应的future阻塞住的控制线程。这种情况下使用ORB对象代理请求的线程与网络Reactor线程池独立负责Reactor的LF线程池不会被其它逻辑影响。但是在LF线程池中进行ORB对象代理请求呢问题就来了。你的LF线程池随时都可能瘫痪掉只要你不小心。极端地LF线程池只有一个线程这个线程在Process事件时进行了ORB对象代理请求阻塞等待future。Good Job!! 这个线程池中唯一的线程就永远不会再有机会成为Leader去取出远端的response的IO事件去唤醒这个阻塞住线程的future了。这还不容易解决都说是线程池那会只有一个线程的呢。我们让这个LF线程池添加到两个线程第一个线程取出事件唤醒第二个线程然后自己处理事件时进行了ORB对象代理请求阻塞等待future第二个线程成为Leader阻塞在多路IO分离函数并在远端response到来时从分离函数返回得以唤醒了阻塞第一个线程的future。但是很不幸第二个线程在等待到response到来之前收到其它IO事件而处理这个事件却进行了ORB对象代理请求阻塞等待future。汗LF线程池都被阻塞在futurefuture又等待IO事件。再往下演绎不论LF线程池有多少线程只要你的处理逻辑中进行了同步阻塞的ORB对象代理请求都会使你的Ice网络处理瘫痪瘫痪的原因是LF线程池瘫痪了。Ice的Server端线程池默认就在当前线程进行请求的dispatch如果你在实现你的服务的时候必须依赖其它ORB对象代理请求时你就要小心了你可能因为这样而阻塞掉所有Communicator的Server端LF线程池至使网络Reactor瘫痪。如果你使用了bidirection connection来提供callback的饲服要是你在callback的实现中依赖了其它ORB对象代理请求时你同样也要小心了你可能因为这样而阻塞掉所有Communicator的Client端LF线程池至使网络Reactor瘫痪。Ice为了避免会默认为每个连接加上一个计时器让连接自动断开。但是我们还是有应用场合希望连接长九不断开关闭这种机制这时就要小心了。再者就是即使你所有的ORB对象请求代理都用异步方式amiamd进行编程但是悲剧的是你无法干涉到你依赖的其它人函数没有进行同步阻塞的ORB对象代理请求。转载于:https://www.cnblogs.com/bbqzsl/p/7462606.html