天天日夜夜添_精品国产99久久久久久人裸体 _成人app在线观看_日韩色网站

新聞資訊

    目錄

    I/O 模型

    • 阻塞式 I/O
    • 非阻塞式 I/O
    • I/O 復用
    • 信號驅動 I/O
    • 異步 I/O
    • 五大 I/O 模型比較

    I/O 復用

    • select
    • poll
    • epoll
    • 工作模式
    • 應用場景

    歡迎關注筆者,優質文章都在這里等你。

    一、I/O 模型

    一個輸入操作通常包括兩個階段:

    • 等待數據準備好
    • 從內核向進程復制數據

    對于一個套接字上的輸入操作,第一步通常涉及等待數據從網絡中到達。當所等待數據到達時,它被復制到內核中的某個緩沖區。第二步就是把數據從內核緩沖區復制到應用進程緩沖區。

    Unix 有五種 I/O 模型:

    • 阻塞式 I/O
    • 非阻塞式 I/O
    • I/O 復用(select 和 poll)
    • 信號驅動式 I/O(SIGIO)
    • 異步 I/O(AIO)

    阻塞式 I/O

    應用進程被阻塞,直到數據從內核緩沖區復制到應用進程緩沖區中才返回。

    應該注意到,在阻塞的過程中,其它應用進程還可以執行,因此阻塞不意味著整個操作系統都被阻塞。因為其它應用進程還可以執行,所以不消耗 CPU 時間,這種模型的 CPU 利用率會比較高。

    下圖中,recvfrom() 用于接收 Socket 傳來的數據,并復制到應用進程的緩沖區 buf 中。這里把 recvfrom() 當成系統調用。

    ssize_t recvfrom(int sockfd, void *buf, size_t len, int flags, struct sockaddr *src_addr, socklen_t *addrlen);
    


    非阻塞式 I/O

    應用進程執行系統調用之后,內核返回一個錯誤碼。應用進程可以繼續執行,但是需要不斷的執行系統調用來獲知 I/O 是否完成,這種方式稱為輪詢(polling)。

    由于 CPU 要處理更多的系統調用,因此這種模型的 CPU 利用率比較低。


    I/O 復用

    使用 select 或者 poll 等待數據,并且可以等待多個套接字中的任何一個變為可讀。這一過程會被阻塞,當某一個套接字可讀時返回,之后再使用 recvfrom 把數據從內核復制到進程中。

    它可以讓單個進程具有處理多個 I/O 事件的能力。又被稱為 Event Driven I/O,即事件驅動 I/O。

    如果一個 Web 服務器沒有 I/O 復用,那么每一個 Socket 連接都需要創建一個線程去處理。如果同時有幾萬個連接,那么就需要創建相同數量的線程。相比于多進程和多線程技術,I/O 復用不需要進程線程創建和切換的開銷,系統開銷更小。


    信號驅動 I/O

    應用進程使用 sigaction 系統調用,內核立即返回,應用進程可以繼續執行,也就是說等待數據階段應用進程是非阻塞的。內核在數據到達時向應用進程發送 SIGIO 信號,應用進程收到之后在信號處理程序中調用 recvfrom 將數據從內核復制到應用進程中。

    相比于非阻塞式 I/O 的輪詢方式,信號驅動 I/O 的 CPU 利用率更高。

    異步 I/O

    應用進程執行 aio_read 系統調用會立即返回,應用進程可以繼續執行,不會被阻塞,內核會在所有操作完成之后向應用進程發送信號。

    異步 I/O 與信號驅動 I/O 的區別在于,異步 I/O 的信號是通知應用進程 I/O 完成,而信號驅動 I/O 的信號是通知應用進程可以開始 I/O。

    五大 I/O 模型比較

    • 同步 I/O:將數據從內核緩沖區復制到應用進程緩沖區的階段,應用進程會阻塞。
    • 異步 I/O:不會阻塞。
    • 阻塞式 I/O、非阻塞式 I/O、I/O 復用和信號驅動 I/O 都是同步 I/O,它們的主要區別在第一個階段。
    • 非阻塞式 I/O 、信號驅動 I/O 和異步 I/O 在第一階段不會阻塞。



    二、I/O 復用

    select/poll/epoll 都是 I/O 多路復用的具體實現,select 出現的最早,之后是 poll,再是 epoll。

    select

    int select(int n, fd_set *readfds, fd_set *writefds, fd_set *exceptfds, struct timeval *timeout);
    

    有三種類型的描述符類型:readset、writeset、exceptset,分別對應讀、寫、異常條件的描述符集合。fd_set 使用數組實現,數組大小使用 FD_SETSIZE 定義。

    timeout 為超時參數,調用 select 會一直阻塞直到有描述符的事件到達或者等待的時間超過 timeout。

    成功調用返回結果大于 0,出錯返回結果為 -1,超時返回結果為 0。

    fd_set fd_in, fd_out;
    struct timeval tv;
    // Reset the sets
    FD_ZERO( &fd_in );
    FD_ZERO( &fd_out );
    // Monitor sock1 for input events
    FD_SET( sock1, &fd_in );
    // Monitor sock2 for output events
    FD_SET( sock2, &fd_out );
    // Find out which socket has the largest numeric value as select requires it
    int largest_sock = sock1 > sock2 ? sock1 : sock2;
    // Wait up to 10 seconds
    tv.tv_sec = 10;
    tv.tv_usec = 0;
    // Call the select
    int ret = select( largest_sock + 1, &fd_in, &fd_out, NULL, &tv );
    // Check if select actually succeed
    if ( ret == -1 )
     // report error and abort
    else if ( ret == 0 )
     // timeout; no event detected
    else
    {
     if ( FD_ISSET( sock1, &fd_in ) )
     // input event on sock1
     if ( FD_ISSET( sock2, &fd_out ) )
     // output event on sock2
    }
    

    poll

    int poll(struct pollfd *fds, unsigned int nfds, int timeout);
    

    pollfd 使用鏈表實現。

    // The structure for two events
    struct pollfd fds[2];
    // Monitor sock1 for input
    fds[0].fd = sock1;
    fds[0].events = POLLIN;
    // Monitor sock2 for output
    fds[1].fd = sock2;
    fds[1].events = POLLOUT;
    // Wait 10 seconds
    int ret = poll( &fds, 2, 10000 );
    // Check if poll actually succeed
    if ( ret == -1 )
     // report error and abort
    else if ( ret == 0 )
     // timeout; no event detected
    else
    {
     // If we detect the event, zero it out so we can reuse the structure
     if ( fds[0].revents & POLLIN )
     fds[0].revents = 0;
     // input event on sock1
     if ( fds[1].revents & POLLOUT )
     fds[1].revents = 0;
     // output event on sock2
    }
    

    比較

    1. 功能

    select 和 poll 的功能基本相同,不過在一些實現細節上有所不同。

    • select 會修改描述符,而 poll 不會;
    • select 的描述符類型使用數組實現,FD_SETSIZE 大小默認為 1024,因此默認只能監聽 1024 個描述符。如果要監聽更多描述符的話,需要修改 FD_SETSIZE 之后重新編譯;而 poll 的描述符類型使用鏈表實現,沒有描述符數量的限制;
    • poll 提供了更多的事件類型,并且對描述符的重復利用上比 select 高。
    • 如果一個線程對某個描述符調用了 select 或者 poll,另一個線程關閉了該描述符,會導致調用結果不確定。

    2. 速度

    select 和 poll 速度都比較慢。

    • select 和 poll 每次調用都需要將全部描述符從應用進程緩沖區復制到內核緩沖區。
    • select 和 poll 的返回結果中沒有聲明哪些描述符已經準備好,所以如果返回值大于 0 時,應用進程都需要使用輪詢的方式來找到 I/O 完成的描述符。

    3. 可移植性

    幾乎所有的系統都支持 select,但是只有比較新的系統支持 poll。

    epoll

    int epoll_create(int size);
    int epoll_ctl(int epfd, int op, int fd, struct epoll_event *event);
    int epoll_wait(int epfd, struct epoll_event * events, int maxevents, int timeout);
    

    epoll_ctl() 用于向內核注冊新的描述符或者是改變某個文件描述符的狀態。已注冊的描述符在內核中會被維護在一棵紅黑樹上,通過回調函數內核會將 I/O 準備好的描述符加入到一個鏈表中管理,進程調用 epoll_wait() 便可以得到事件完成的描述符。

    從上面的描述可以看出,epoll 只需要將描述符從進程緩沖區向內核緩沖區拷貝一次,并且進程不需要通過輪詢來獲得事件完成的描述符。

    epoll 僅適用于 Linux OS。

    epoll 比 select 和 poll 更加靈活而且沒有描述符數量限制。

    epoll 對多線程編程更有友好,一個線程調用了 epoll_wait() 另一個線程關閉了同一個描述符也不會產生像 select 和 poll 的不確定情況。

    // Create the epoll descriptor. Only one is needed per app, and is used to monitor all sockets.
    // The function argument is ignored (it was not before, but now it is), so put your favorite number here
    int pollingfd = epoll_create( 0xCAFE );
    if ( pollingfd < 0 )
     // report error
    // Initialize the epoll structure in case more members are added in future
    struct epoll_event ev = { 0 };
    // Associate the connection class instance with the event. You can associate anything
    // you want, epoll does not use this information. We store a connection class pointer, pConnection1
    ev.data.ptr = pConnection1;
    // Monitor for input, and do not automatically rearm the descriptor after the event
    ev.events = EPOLLIN | EPOLLONESHOT;
    // Add the descriptor into the monitoring list. We can do it even if another thread is
    // waiting in epoll_wait - the descriptor will be properly added
    if ( epoll_ctl( epollfd, EPOLL_CTL_ADD, pConnection1->getSocket(), &ev ) != 0 )
     // report error
    // Wait for up to 20 events (assuming we have added maybe 200 sockets before that it may happen)
    struct epoll_event pevents[ 20 ];
    // Wait for 10 seconds, and retrieve less than 20 epoll_event and store them into epoll_event array
    int ready = epoll_wait( pollingfd, pevents, 20, 10000 );
    // Check if epoll actually succeed
    if ( ret == -1 )
     // report error and abort
    else if ( ret == 0 )
     // timeout; no event detected
    else
    {
     // Check if any events detected
     for ( int i = 0; i < ret; i++ )
     {
     if ( pevents[i].events & EPOLLIN )
     {
     // Get back our connection pointer
     Connection * c = (Connection*) pevents[i].data.ptr;
     c->handleReadEvent();
     }
     }
    }
    

    工作模式

    epoll 的描述符事件有兩種觸發模式:LT(level trigger)和 ET(edge trigger)。

    1. LT 模式

    當 epoll_wait() 檢測到描述符事件到達時,將此事件通知進程,進程可以不立即處理該事件,下次調用 epoll_wait() 會再次通知進程。是默認的一種模式,并且同時支持 Blocking 和 No-Blocking。

    2. ET 模式

    和 LT 模式不同的是,通知之后進程必須立即處理事件,下次再調用 epoll_wait() 時不會再得到事件到達的通知。

    很大程度上減少了 epoll 事件被重復觸發的次數,因此效率要比 LT 模式高。只支持 No-Blocking,以避免由于一個文件句柄的阻塞讀/阻塞寫操作把處理多個文件描述符的任務餓死。

    應用場景

    很容易產生一種錯覺認為只要用 epoll 就可以了,select 和 poll 都已經過時了,其實它們都有各自的使用場景。

    1. select 應用場景

    select 的 timeout 參數精度為 1ns,而 poll 和 epoll 為 1ms,因此 select 更加適用于實時性要求比較高的場景,比如核反應堆的控制。

    select 可移植性更好,幾乎被所有主流平臺所支持。

    2. poll 應用場景

    poll 沒有最大描述符數量的限制,如果平臺支持并且對實時性要求不高,應該使用 poll 而不是 select。

    3. epoll 應用場景

    只需要運行在 Linux 平臺上,有大量的描述符需要同時輪詢,并且這些連接最好是長連接。

    需要同時監控小于 1000 個描述符,就沒有必要使用 epoll,因為這個應用場景下并不能體現 epoll 的優勢。

    需要監控的描述符狀態變化多,而且都是非常短暫的,也沒有必要使用 epoll。因為 epoll 中的所有描述符都存儲在內核中,造成每次需要對描述符的狀態改變都需要通過 epoll_ctl() 進行系統調用,頻繁系統調用降低效率。并且 epoll 的描述符存儲在內核,不容易調試。

    資料來源 : github 作者 : CyC2018


    您的轉發+關注就是對筆者最大的支持,歡迎關注。

    對大廠架構設計,BAT面試題分享,編程語言理論或者互聯網圈逸聞趣事這些感興趣,歡迎關注筆者,沒有錯,干貨文章都在這里。


    引言

    FDS945-NL場效應管在高速發展的電子元件行業里,因其出色的性能和廣泛應用,已成為方案工程師、技術人員和制造購置的焦點。這款P溝MOSFET不但因其出色的電氣特性在市場中占有重要地位,并且在推進電子設計制造業技術革新方面發揮著主導地位。FDS945-NL不僅是電子元件行業的提高,都是現代電子技術發展的象征。

    技術規格參數詳解

    FDS945-NL的技術參數充分展示了其在高性能MOS管里的領先地位。它有60VP溝漏電源電流(Vdss)持續漏極電流做到50A(Id),主要應用于髙壓、大電流的使用場景。其導通電阻僅是20mΩ(在10V, 在50A環境下),這種低電阻特性顯著降低了高效導出時的能量損失,確保了系統在高性能工作情況下的穩定性和可靠性,并把FDS9945-NL推廣到電子設計里的挑選元件。

    工作原理

    FDS9945-NL工作原理是根據P溝MOSFET的關鍵系統。依據電場調整電流流動,進行更有效的電流調整。FDS945-NL不僅提升了電源靈活性,并且比傳統電子元件在電池管理和信號調節方面表現出更高的效率和穩定性。FDS9945-NL在高電流和高電壓情況下的出色表現,使FDS9945-NL在現代電子設計中具有獨特的優勢,主要適用于復雜而嚴苛的應用場景。

    電路應用方案

    FDS9945-NL在電子線路的設計和應用中起著重要作用。廣泛用于電源管理系統、電池充電器、信號增強器等關鍵領域。FDS9945-NL的出色電氣特性不僅提升了這些設備的綜合性能和品質,并且在處理大電流和高電壓問題時也表現出了其特點和優勢。該應用案例證明了FDS945-NL的多功能化,并顯示了其在提升電子產品性能層面的必要性。

    結論

    一般來說,FDS945-NL場效應管以其優質的技術參數和優良工作原理但在電子元件市場獲得普遍認可。這是方案工程師、技術人員和生產商在挑選高效元件時的理想選擇。FDS945-NL不僅促進了電子產業的技術創新,并且在提高產品特性方面發揮了重要作用。

網站首頁   |    關于我們   |    公司新聞   |    產品方案   |    用戶案例   |    售后服務   |    合作伙伴   |    人才招聘   |   

友情鏈接: 餐飲加盟

地址:北京市海淀區    電話:010-     郵箱:@126.com

備案號:冀ICP備2024067069號-3 北京科技有限公司版權所有