日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

web----epoll实现原理

發布時間:2023/12/10 编程问答 21 豆豆
生活随笔 收集整理的這篇文章主要介紹了 web----epoll实现原理 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

epoll可以用單進程單線程實現高并發

首先我們可以實現單進程單線程實現高并發(模擬非阻塞IO請求)

服務端

//服務端 public class BlockNIOServer {public static void main(String[] args) throws IOException, InterruptedException {//獲取通道ServerSocketChannel serverSocketChannel = ServerSocketChannel.open();//切換非阻塞模式serverSocketChannel.configureBlocking(false);//綁定端口serverSocketChannel.bind(new InetSocketAddress(8090));//獲取選擇器Selector selector = Selector.open();//將該通道注冊到select中,讓select監聽該通道的連接是否準備就緒serverSocketChannel.register(selector, SelectionKey.OP_ACCEPT);Iterator<SelectionKey> iterator = null;//通過選擇器輪詢獲取已經準備就緒的事件while (selector.select()>0){iterator = selector.selectedKeys().iterator();while (iterator.hasNext()){SelectionKey selectionKey = iterator.next();//如果獲取的是準備連接就緒的事件if (selectionKey.isAcceptable()){System.out.println("有客戶端已經準備好連接了....");//開始接受連接客戶端SocketChannel accept = serverSocketChannel.accept();//切換非阻塞模式accept.configureBlocking(false);//將通道注冊到selector中,讓select監聽該通道的數據是否準備就緒accept.register(selector,SelectionKey.OP_READ);}else if (selectionKey.isReadable()){SocketChannel socketChannel = (SocketChannel) selectionKey.channel();Random random = new Random();int i = random.nextInt(100);String path = "C:\\Users\\zhengyan\\Desktop\\test1\\"+i+".txt";FileChannel fileChannel = FileChannel.open(Paths.get(path), StandardOpenOption.READ, StandardOpenOption.WRITE, StandardOpenOption.CREATE);ByteBuffer byteBuffer = ByteBuffer.allocate(1024);while (socketChannel.read(byteBuffer)!=-1){byteBuffer.flip();fileChannel.write(byteBuffer);byteBuffer.clear();}byteBuffer.put("數據已經接受完畢...".getBytes());byteBuffer.flip();socketChannel.write(byteBuffer);fileChannel.close();socketChannel.close();System.out.println("寫入數據成功....");}//取消選擇鍵iterator.remove();}}} }

客戶端

//客戶端 public class BlockNIOClient {public static void main(String[] args) throws IOException, InterruptedException {//獲取通道SocketChannel socketChannel = SocketChannel.open(new InetSocketAddress("127.0.0.1", 8090));FileChannel fileChannel = FileChannel.open(Paths.get("C:\\Users\\zhengyan\\Desktop\\test1\\x.txt"), StandardOpenOption.READ);//System.out.println("模擬10秒之后發送數據...");//可以開啟兩個客戶端,一個睡10秒發送數據(先請求),一個不用睡眠(后請求),發現,必須等第一個用戶處理完畢之后,第二個用戶才可以被處理//Thread.sleep(20000);//分配緩沖區大小ByteBuffer byteBuffer = ByteBuffer.allocate(1024);//讀取本地文件發送到服務器while (fileChannel.read(byteBuffer)!=-1){byteBuffer.flip();socketChannel.write(byteBuffer);byteBuffer.clear();}//告訴服務器,我的數據已經發送完畢socketChannel.shutdownOutput();//接受服務器返回來的消息StringBuffer stringBuffer = new StringBuffer();int len =-1;while ((len=socketChannel.read(byteBuffer))!=-1){byteBuffer.flip();stringBuffer.append(new String(byteBuffer.array(),0,len));byteBuffer.clear();}System.out.println(stringBuffer);socketChannel.close();fileChannel.close();} }

假如有三個連接到來了,一個socker通道監聽連接是否到來(白色方格),三個socker通道是因為連接到來了,被注冊到select中監聽數據是否到來(黃色方格),此時select不斷的遍歷,首先select將其中的一個socker通道(在linux中是fd(int)文件描述符)復制一份到操作系統(這一步是性能的瓶頸所在,讓操作提供來看看我這個通道有沒有數據到來,或者連接請求的到來),此時操作系統(內核)還會執行別的應用進程,什么執行我們這個檢測操作是由操作系統決定(又浪費了一部分時間)。然后一步一步將select選擇器中的所有的socket通道全部遍歷(select選擇器中的socker通道數目越多,性能越差),有的socker通道不活躍,也被檢測了,就非常損耗性能。

圖中綠色的是select選擇器(維護了socker通道),處于應用層,放在用戶空間

?

?

epoll

epoll有一段特殊的內存空間(操作系統和應用程序共用)

圖中綠色的是epoll選擇器(維護了socker通道,實現方式是紅黑樹和鏈表),處于應用程序和內核共享空間

epoll的第一個優點:不需要額外的復制操作

?

epoll的第一個優點:采用事件通知,取代了之前的輪詢(select)

?

轉載于:https://www.cnblogs.com/yanxiaoge/p/11563609.html

總結

以上是生活随笔為你收集整理的web----epoll实现原理的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。