<output id="qn6qe"></output>

    1. <output id="qn6qe"><tt id="qn6qe"></tt></output>
    2. <strike id="qn6qe"></strike>

      亚洲 日本 欧洲 欧美 视频,日韩中文字幕有码av,一本一道av中文字幕无码,国产线播放免费人成视频播放,人妻少妇偷人无码视频,日夜啪啪一区二区三区,国产尤物精品自在拍视频首页,久热这里只有精品12

      服務器項目實戰(zhàn)與總結(五)

      服務器項目實戰(zhàn)與總結(五)

      阻塞和非阻塞、同步和異步

       

       

       

       

       

       同步:是應用程序自己主動讀取的,是從內核中的TCP接收緩沖區(qū)的數(shù)據(jù)主動搬到用戶區(qū),比如recv/read函數(shù)。

      異步:不是應用程序自己主動讀取的,應用程序只需要告訴操作系統(tǒng)通信方式等,然后操作系統(tǒng)搬運數(shù)據(jù)到用戶區(qū),并通知應用程序它把數(shù)據(jù)搬運好了。

       

      Unix、Linux上的五種IO模型

       

       

       

      a. 阻塞

      調用者調用了某個函數(shù),等待這個函數(shù)返回,期間什么也不做,不停的去檢查這個函數(shù)有沒有返回,必須等這個函數(shù)返回才能進行下一步動作。

       

       

       

      b.非阻塞(NIO)

      非阻塞等待,每隔一段時間就去檢測IO事件是否就緒。沒有就緒就可以做其他事。非阻塞I/O執(zhí)行系統(tǒng)調用總是立即返回,不管事件是否已經發(fā)生,若事件沒有發(fā)生,則返回-1,此時可以根據(jù) errno 區(qū)分這兩種情況,對于accept,recv 和 send,事件未發(fā)生時,errno 通常被設置成 EAGAIN。

       

       

       

      c.IO復用

      非阻塞等待,每隔一段時間就去檢測IO事件是否就緒。沒有就緒就可以做其他事。非阻塞I/O執(zhí)行系統(tǒng)調用總是立即返回,不管事件是否已經發(fā)生,若事件沒有發(fā)生,則返回-1,此時可以根據(jù) errno 區(qū)分這兩種情況,對于accept,recv 和 send,事件未發(fā)生時,errno 通常被設置成 EAGAIN。

       

       

       d.信號驅動

      Linux 用套接口進行信號驅動 IO,安裝一個信號處理函數(shù),進程繼續(xù)運行并不阻塞,當IO事件就緒,進
      程收到SIGIO 信號,然后處理 IO 事件。

      內核在第一個階段是異步,在第二個階段是同步;與非阻塞IO的區(qū)別在于它提供了消息通知機制,不需
      要用戶進程不斷的輪詢檢查,減少了系統(tǒng)API的調用次數(shù),提高了效率。

       

       

       e.異步

      Linux中,可以調用 aio_read 函數(shù)告訴內核描述字緩沖區(qū)指針和緩沖區(qū)的大小、文件偏移及通知的方
      式,然后立即返回,當內核將數(shù)據(jù)拷貝到緩沖區(qū)后,再通知應用程序。

       

       

       

       

       

       

      Web服務器簡介及HTTP協(xié)議

      一個 Web Server 就是一個服務器軟件(程序),或者是運行這個服務器軟件的硬件(計算機)。其主
      要功能是通過 HTTP 協(xié)議與客戶端(通常是瀏覽器(Browser))進行通信,來接收,存儲,處理來自
      客戶端的 HTTP 請求,并對其請求做出 HTTP 響應,返回給客戶端其請求的內容(文件、網(wǎng)頁等)或返
      回一個 Error 信息。

       

       

       

      通常用戶使用 Web 瀏覽器與相應服務器進行通信。在瀏覽器中鍵入“域名”或“IP地址:端口號”,瀏覽器則
      先將你的域名解析成相應的 IP 地址或者直接根據(jù)你的IP地址向對應的 Web 服務器發(fā)送一個 HTTP 請
      求。這一過程首先要通過 TCP 協(xié)議的三次握手建立與目標 Web 服務器的連接,然后 HTTP 協(xié)議生成針
      對目標 Web 服務器的 HTTP 請求報文,通過 TCP、IP 等協(xié)議發(fā)送到目標 Web 服務器上。

      HTTP協(xié)議(應用層的協(xié)議)

       

       

       

       

       

       

       

       

       

      https協(xié)議默認端口是443

      HTTP 請求報文格式

       

       

       

      例如,HTTP請求頭部原始信息:

       1 GET /topics/391887078 HTTP/2
       2 Host: bbs.csdn.net
       3 User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:97.0) Gecko/20100101 Firefox/97.0
       4 Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,*/*;q=0.8
       5 Accept-Language: zh-CN,zh;q=0.8,zh-TW;q=0.7,zh-HK;q=0.5,en-US;q=0.3,en;q=0.2
       6 Accept-Encoding: gzip, deflate, br
       7 Referer: https://www.baidu.com/link?url=NZx_amw_JwKNfYbX5eBYtLsusVpiKpup9kp5fn7G5m5y6T0Je5Xdw8j4Vw2erCor&wd=&eqid=b590649600029c9000000005621f30a1
       8 Connection: keep-alive
       9 Cookie: uuid_tt_dd=10_37405684820-1640156095208-848782; log_Id_pv=43; Hm_lvt_6bcd52f51e9b3dce32bec4a3997715ac=1646229342,1646381047,1646724951,1646724980; Hm_up_6bcd52f51e9b3dce32bec4a3997715ac=%7B%22islogin%22%3A%7B%22value%22%3A%221%22%2C%22scope%22%3A1%7D%2C%22isonline%22%3A%7B%22value%22%3A%221%22%2C%22scope%22%3A1%7D%2C%22isvip%22%3A%7B%22value%22%3A%220%22%2C%22scope%22%3A1%7D%2C%22uid_%22%3A%7B%22value%22%3A%22qq_59374912%22%2C%22scope%22%3A1%7D%7D; Hm_ct_6bcd52f51e9b3dce32bec4a3997715ac=6525*1*10_37405684820-1640156095208-848782!5744*1*qq_59374912; log_Id_view=422; log_Id_click=15; __gads=ID=6a47c56ca9b87d48-22fa344982cf0021:T=1640156105:RT=1640156105:S=ALNI_MbXxcGg5d8Q8Gk0uY7yiJkJlILCjw; ssxmod_itna=eqfhGIxRhGkDCzDXbRx0InqDq7I5GQ=G3qW=beDl=CYxA5D8D6DQeGTbu5Cb3=HYjEh3h1jADnKFkBA+uRdkFt7f3pkmDb4GLDmKDySj10FDx1q0rD74irDDxD3ExWKDwDlKDgDQKZyExDaDGck302kDimHSr5sDiH5ot0DXxG1DQ5DsrGIklKD06OvkDDd33opuY4DUDRDj94LeCrqqDi3fmKzBx0OD09sDme7l2fCyDGa4vA0I1LF5CpdsxKDmh5DyhgkyeBka2SKDjukavrgDGHKbmcbOE0xYAm41Gb5cLnq=GXP6VVKDDW5B4VkD4D==; ssxmod_itna2=eqfhGIxRhGkDCzDXbRx0InqDq7I5GQ=G3qW=D6h92D0H9K03G1=2je6qN27u5SSnTK=12m=ArLqZS1gbd42Dn+0m6ja6vbiW64pgnUHXi1jbzYatAMyAyC+=I6Llmzal2s38=15aI0kxX+TjxAfj1SqmqZT6/b+393Qb5y4RRlu3plT3d2DR03BbVBrQySWbzD=aVAMxYPSn4uCGqXbKVUaoO6ZbsVefrvbhdOWbmG+efATEqRltpY0WSWtLeHL2u8ELm=RX7iBMkMGkf+/6EbWOuK4PDKkwFD7=DekqxD==; UserName=qq_59374912; UserInfo=5407bd51ea8f4231b7daaea5cb1b87d9; UserToken=5407bd51ea8f4231b7daaea5cb1b87d9; UserNick=%E5%AE%9E%E5%B9%B2375; AU=1B5; UN=qq_59374912; BT=1641803856440; p_uid=U000000; dc_sid=186a79b8d2fbe0fa93b76b7d5315051b; c_pref=https%3A//www.baidu.com/link; c_ref=https%3A//www.baidu.com/link; c_first_ref=www.baidu.com; c_first_page=https%3A//bbs.csdn.net/topics/391887078; c_segment=14; Hm_lpvt_6bcd52f51e9b3dce32bec4a3997715ac=1646724980; c_dl_prid=1646211467077_827614; c_dl_rid=1646211629296_539584; c_dl_fref=https://www.baidu.com/link; c_dl_fpage=/download/zsf250/10880412; c_dl_um=distribute.pc_aggpage_search_result.none-task-download-2%7Eaggregatepage%7Efirst_rank_ecpm_v1%7Erank_v31_ecpm-1-10880412.pc_agg_new_rank; csrfToken=2vdK7sXuLQapQ9JA68jKqDfd; dc_session_id=10_1646548189085.802620; dc_tos=r8f14j; c_page_id=default; FCNEC=[["AKsRol-GBWj_ZDmUuf7GGbQB1YuX6J-HDa1B1I-ytK-zIMCkE1mtQgjQ28bO9HJNF87kKMUQCuzsKtiOAGWX4dqza2ErJx3HxQCdz_-8DFKoP7wHFBPoWlCTmOqHJtkOJhbH_0_VJHXhmL8MAFwf4QlHl3y7Sf1WNg=="],null,[]]
      10 Upgrade-Insecure-Requests: 1
      11 Sec-Fetch-Dest: document
      12 Sec-Fetch-Mode: navigate
      13 Sec-Fetch-Site: cross-site
      14 Cache-Control: max-age=0

       

      HTTP響應報文格式

       

       

       例如:

       1 HTTP/2 200 OK
       2 server: openresty
       3 date: Tue, 08 Mar 2022 07:43:54 GMT
       4 content-type: text/html; charset=utf-8
       5 vary: Accept-Encoding
       6 x-response-time: 118
       7 x-xss-protection: 1; mode=block
       8 x-content-type-options: nosniff
       9 x-download-options: noopen
      10 x-readtime: 118
      11 strict-transport-security: max-age=31536000
      12 content-encoding: gzip
      13 X-Firefox-Spdy: h2

       

      HTTP請求方法

      HTTP/1.1 協(xié)議中共定義了八種方法(也叫“動作”)來以不同方式操作指定的資源:

      1. GET:向指定的資源發(fā)出“顯示”請求。使用 GET 方法應該只用在讀取數(shù)據(jù),而不應當被用于產生“副
      作用”的操作中,例如在 Web Application 中。其中一個原因是 GET 可能會被網(wǎng)絡蜘蛛等隨意訪
      問。
      2. HEAD:與 GET 方法一樣,都是向服務器發(fā)出指定資源的請求。只不過服務器將不傳回資源的本文
      部分。它的好處在于,使用這個方法可以在不必傳輸全部內容的情況下,就可以獲取其中“關于該
      資源的信息”(元信息或稱元數(shù)據(jù))。
      3. POST:向指定資源提交數(shù)據(jù),請求服務器進行處理(例如提交表單或者上傳文件)。數(shù)據(jù)被包含
      在請求本文中。這個請求可能會創(chuàng)建新的資源或修改現(xiàn)有資源,或二者皆有。
      4. PUT:向指定資源位置上傳其最新內容。
      5. DELETE:請求服務器刪除 Request-URI 所標識的資源。
      6. TRACE:回顯服務器收到的請求,主要用于測試或診斷。
      7. OPTIONS:這個方法可使服務器傳回該資源所支持的所有 HTTP 請求方法。用'*'來代替資源名稱,
      向 Web 服務器發(fā)送 OPTIONS 請求,可以測試服務器功能是否正常運作。
      8. CONNECT:HTTP/1.1 協(xié)議中預留給能夠將連接改為管道方式的代理服務器。通常用于SSL加密服
      務器的鏈接(經由非加密的 HTTP 代理服務器)。

       

      補充,面試考:get和post請求的區(qū)別

      GET比POST更不安全,因為參數(shù)直接暴露在URL上,所以不能用來傳遞敏感信息。

       

      GET和POST還有一個重大區(qū)別,簡單的說:

      GET產生一個TCP數(shù)據(jù)包;POST產生兩個TCP數(shù)據(jù)包。

      長的說:

      對于GET方式的請求,瀏覽器會把http header和data一并發(fā)送出去,服務器響應200(返回數(shù)據(jù));

      而對于POST,瀏覽器先發(fā)送header,服務器響應100 continue,瀏覽器再發(fā)送data,服務器響應200 ok(返回數(shù)據(jù))。

      也就是說,GET只需要汽車跑一趟就把貨送到了,而POST得跑兩趟,第一趟,先去和服務器打個招呼“嗨,我等下要送一批貨來,你們打開門迎接我”,然后再回頭把貨送過去。

      因為POST需要兩步,時間上消耗的要多一點,看起來GET比POST更有效。因此Yahoo團隊有推薦用GET替換POST來優(yōu)化網(wǎng)站性能。但這是一個坑!跳入需謹慎。為什么?

      1. GET與POST都有自己的語義,不能隨便混用。

      2. 據(jù)研究,在網(wǎng)絡環(huán)境好的情況下,發(fā)一次包的時間和發(fā)兩次包的時間差別基本可以無視。而在網(wǎng)絡環(huán)境差的情況下,兩次包的TCP在驗證數(shù)據(jù)包完整性上,有非常大的優(yōu)點。

      3. 并不是所有瀏覽器都會在POST中發(fā)送兩次包,F(xiàn)irefox就只發(fā)送一次。

       

      HTTP狀態(tài)碼

       

       

       

      服務器編程基本框架和兩種高效的事件處理模式

      服務器編程基本框架

      雖然服務器程序種類繁多,但其基本框架都一樣,不同之處在于邏輯處理。

       

       

       

       

        兩種高效的事件處理模式

      服務器程序通常需要處理三類事件:I/O 事件、信號及定時事件。有兩種高效的事件處理模式:Reactor
      和 Proactor,同步 I/O 模型通常用于實現(xiàn) Reactor 模式,異步 I/O 模型通常用于實現(xiàn) Proactor 模式。

      Reactor模式

      要求主線程(I/O處理單元)只負責監(jiān)聽文件描述符上是否有事件發(fā)生,有的話就立即將該事件通知工作
      線程(邏輯單元),將 socket 可讀可寫事件放入請求隊列,交給工作線程處理。除此之外,主線程不做
      任何其他實質性的工作。讀寫數(shù)據(jù),接受新的連接,以及處理客戶請求均在工作線程中完成。
      使用同步 I/O(以 epoll_wait 為例)實現(xiàn)的 Reactor 模式的工作流程是:
      1. 主線程往 epoll 內核事件表中注冊 socket 上的讀就緒事件。
      2. 主線程調用 epoll_wait 等待 socket 上有數(shù)據(jù)可讀。
      3. 當 socket 上有數(shù)據(jù)可讀時, epoll_wait 通知主線程。主線程則將 socket 可讀事件放入請求隊列。
      4. 睡眠在請求隊列上的某個工作線程被喚醒,它從 socket 讀取數(shù)據(jù),并處理客戶請求,然后往 epoll
      內核事件表中注冊該 socket 上的寫就緒事件。
      5. 當主線程調用 epoll_wait 等待 socket 可寫。
      6. 當 socket 可寫時,epoll_wait 通知主線程。主線程將 socket 可寫事件放入請求隊列。
      7. 睡眠在請求隊列上的某個工作線程被喚醒,它往 socket 上寫入服務器處理客戶請求的結果。

       

      Reactor 模式的工作流程:

       

       Proactor模式

      Proactor 模式將所有 I/O 操作都交給主線程和內核來處理(進行讀、寫),工作線程僅僅負責業(yè)務邏
      輯。使用異步 I/O 模型(以 aio_read 和 aio_write 為例)實現(xiàn)的 Proactor 模式的工作流程是:
      1. 主線程調用 aio_read 函數(shù)向內核注冊 socket 上的讀完成事件,并告訴內核用戶讀緩沖區(qū)的位置,
      以及讀操作完成時如何通知應用程序(這里以信號為例)。
      2. 主線程繼續(xù)處理其他邏輯。
      3. 當 socket 上的數(shù)據(jù)被讀入用戶緩沖區(qū)后,內核將向應用程序發(fā)送一個信號,以通知應用程序數(shù)據(jù)
      已經可用。
      4. 應用程序預先定義好的信號處理函數(shù)選擇一個工作線程來處理客戶請求。工作線程處理完客戶請求
      后,調用 aio_write 函數(shù)向內核注冊 socket 上的寫完成事件,并告訴內核用戶寫緩沖區(qū)的位置,以
      及寫操作完成時如何通知應用程序。
      5. 主線程繼續(xù)處理其他邏輯。
      6. 當用戶緩沖區(qū)的數(shù)據(jù)被寫入 socket 之后,內核將向應用程序發(fā)送一個信號,以通知應用程序數(shù)據(jù)
      已經發(fā)送完畢。
      7. 應用程序預先定義好的信號處理函數(shù)選擇一個工作線程來做善后處理,比如決定是否關閉 socket。

      Proactor 模式的工作流程:

       

       模擬 Proactor 模式

      使用同步 I/O 方式模擬出 Proactor 模式。原理是:主線程執(zhí)行數(shù)據(jù)讀寫操作,讀寫完成之后,主線程向
      工作線程通知這一”完成事件“。那么從工作線程的角度來看,它們就直接獲得了數(shù)據(jù)讀寫的結果,接下
      來要做的只是對讀寫的結果進行邏輯處理。
      使用同步 I/O 模型(以 epoll_wait為例)模擬出的 Proactor 模式的工作流程如下:
      1. 主線程往 epoll 內核事件表中注冊 socket 上的讀就緒事件。
      2. 主線程調用 epoll_wait 等待 socket 上有數(shù)據(jù)可讀。
      3. 當 socket 上有數(shù)據(jù)可讀時,epoll_wait 通知主線程。主線程從 socket 循環(huán)讀取數(shù)據(jù),直到沒有更
      多數(shù)據(jù)可讀,然后將讀取到的數(shù)據(jù)封裝成一個請求對象并插入請求隊列。
      4. 睡眠在請求隊列上的某個工作線程被喚醒,它獲得請求對象并處理客戶請求,然后往 epoll 內核事
      件表中注冊 socket 上的寫就緒事件。
      5. 主線程調用 epoll_wait 等待 socket 可寫。
      6. 當 socket 可寫時,epoll_wait 通知主線程。主線程往 socket 上寫入服務器處理客戶請求的結果。

      同步 I/O 模擬 Proactor 模式的工作流程:

       

       

      線程同步機制類封裝及線程池實現(xiàn)

      線程池

      線程池是由服務器預先創(chuàng)建的一組子線程,線程池中的線程數(shù)量應該和 CPU 數(shù)量差不多。線程池中的所
      有子線程都運行著相同的代碼。當有新的任務到來時,主線程將通過某種方式選擇線程池中的某一個子
      線程來為之服務。相比與動態(tài)的創(chuàng)建子線程,選擇一個已經存在的子線程的代價顯然要小得多。至于主
      線程選擇哪個子線程來為新任務服務,則有多種方式:
      主線程使用某種算法來主動選擇子線程。最簡單、最常用的算法是隨機算法和 Round Robin(輪流
      選取)算法,但更優(yōu)秀、更智能的算法將使任務在各個工作線程中更均勻地分配,從而減輕服務器
      的整體壓力。
      主線程和所有子線程通過一個共享的工作隊列來同步,子線程都睡眠在該工作隊列上。當有新的任
      務到來時,主線程將任務添加到工作隊列中。這將喚醒正在等待任務的子線程,不過只有一個子線
      程將獲得新任務的”接管權“,它可以從工作隊列中取出任務并執(zhí)行之,而其他子線程將繼續(xù)睡眠在
      工作隊列上。

       

      線程池的一般模型為:

       

       

      代碼

      locker.c

        1 #ifndef LOCKER_H
        2 #define LOCKER_H
        3 
        4 #include <exception>
        5 #include <pthread.h>
        6 #include <semaphore.h>
        7 
        8 // 線程同步機制封裝類
        9 
       10 // 互斥鎖類
       11 class locker {
       12 public:
       13     locker() {
       14         if(pthread_mutex_init(&m_mutex, NULL) != 0) {
       15             throw std::exception();
       16         }
       17     }
       18 
       19     ~locker() {
       20         pthread_mutex_destroy(&m_mutex);
       21     }
       22 
       23     bool lock() {
       24         return pthread_mutex_lock(&m_mutex) == 0;
       25     }
       26 
       27     bool unlock() {
       28         return pthread_mutex_unlock(&m_mutex) == 0;
       29     }
       30 
       31     pthread_mutex_t *get()
       32     {
       33         return &m_mutex;
       34     }
       35 
       36 private:
       37     pthread_mutex_t m_mutex;
       38 };
       39 
       40 
       41 // 條件變量類
       42 class cond {
       43 public:
       44     cond(){
       45         if (pthread_cond_init(&m_cond, NULL) != 0) {
       46             throw std::exception();
       47         }
       48     }
       49     ~cond() {
       50         pthread_cond_destroy(&m_cond);
       51     }
       52 
       53     bool wait(pthread_mutex_t *m_mutex) {
       54         int ret = 0;
       55         ret = pthread_cond_wait(&m_cond, m_mutex);
       56         return ret == 0;
       57     }
       58     bool timewait(pthread_mutex_t *m_mutex, struct timespec t) {
       59         int ret = 0;
       60         ret = pthread_cond_timedwait(&m_cond, m_mutex, &t);
       61         return ret == 0;
       62     }
       63     bool signal() {
       64         return pthread_cond_signal(&m_cond) == 0;
       65     }
       66     bool broadcast() {
       67         return pthread_cond_broadcast(&m_cond) == 0;
       68     }
       69 
       70 private:
       71     pthread_cond_t m_cond;
       72 };
       73 
       74 
       75 // 信號量類
       76 class sem {
       77 public:
       78     sem() {
       79         if( sem_init( &m_sem, 0, 0 ) != 0 ) {
       80             throw std::exception();
       81         }
       82     }
       83     sem(int num) {
       84         if( sem_init( &m_sem, 0, num ) != 0 ) {
       85             throw std::exception();
       86         }
       87     }
       88     ~sem() {
       89         sem_destroy( &m_sem );
       90     }
       91     // 等待信號量
       92     bool wait() {
       93         return sem_wait( &m_sem ) == 0;
       94     }
       95     // 增加信號量
       96     bool post() {
       97         return sem_post( &m_sem ) == 0;
       98     }
       99 private:
      100     sem_t m_sem;
      101 };
      102 
      103 #endif

       

      threadpoll.c

        1 #ifndef THREADPOOL_H
        2 #define THREADPOOL_H
        3 
        4 #include <list>
        5 #include <cstdio>
        6 #include <exception>
        7 #include <pthread.h>
        8 #include "locker.h"
        9 
       10 // 線程池類,將它定義為模板類是為了代碼復用,模板參數(shù)T是任務類
       11 template<typename T>
       12 class threadpool {
       13 public:
       14     /*thread_number是線程池中線程的數(shù)量,max_requests是請求隊列中最多允許的、等待處理的請求的數(shù)量*/
       15     threadpool(int thread_number = 8, int max_requests = 10000);
       16     ~threadpool();
       17     bool append(T* request);
       18 
       19 private:
       20     /*工作線程運行的函數(shù),它不斷從工作隊列中取出任務并執(zhí)行之*/
       21     static void* worker(void* arg);
       22     void run();
       23 
       24 private:
       25     // 線程的數(shù)量
       26     int m_thread_number;  
       27     
       28     // 描述線程池的數(shù)組,大小為m_thread_number    
       29     pthread_t * m_threads;
       30 
       31     // 請求隊列中最多允許的、等待處理的請求的數(shù)量  
       32     int m_max_requests; 
       33     
       34     // 請求隊列
       35     std::list< T* > m_workqueue;  
       36 
       37     // 保護請求隊列的互斥鎖
       38     locker m_queuelocker;   
       39 
       40     // 是否有任務需要處理
       41     sem m_queuestat;
       42 
       43     // 是否結束線程          
       44     bool m_stop;                    
       45 };
       46 
       47 template< typename T >
       48 threadpool< T >::threadpool(int thread_number, int max_requests) : 
       49         m_thread_number(thread_number), m_max_requests(max_requests), 
       50         m_stop(false), m_threads(NULL) {
       51 
       52     if((thread_number <= 0) || (max_requests <= 0) ) {
       53         throw std::exception();
       54     }
       55 
       56     m_threads = new pthread_t[m_thread_number];
       57     if(!m_threads) {
       58         throw std::exception();
       59     }
       60 
       61     // 創(chuàng)建thread_number 個線程,并將他們設置為脫離線程。
       62     for ( int i = 0; i < thread_number; ++i ) {
       63         printf( "create the %dth thread\n", i);
       64         if(pthread_create(m_threads + i, NULL, worker, this ) != 0) {
       65             delete [] m_threads;
       66             throw std::exception();
       67         }
       68         
       69         if( pthread_detach( m_threads[i] ) ) {
       70             delete [] m_threads;
       71             throw std::exception();
       72         }
       73     }
       74 }
       75 
       76 template< typename T >
       77 threadpool< T >::~threadpool() {
       78     delete [] m_threads;
       79     m_stop = true;
       80 }
       81 
       82 template< typename T >
       83 bool threadpool< T >::append( T* request )
       84 {
       85     // 操作工作隊列時一定要加鎖,因為它被所有線程共享。
       86     m_queuelocker.lock();
       87     if ( m_workqueue.size() > m_max_requests ) {
       88         m_queuelocker.unlock();
       89         return false;
       90     }
       91     m_workqueue.push_back(request);
       92     m_queuelocker.unlock();
       93     m_queuestat.post();
       94     return true;
       95 }
       96 
       97 template< typename T >
       98 void* threadpool< T >::worker( void* arg )
       99 {
      100     threadpool* pool = ( threadpool* )arg;
      101     pool->run();
      102     return pool;
      103 }
      104 
      105 template< typename T >
      106 void threadpool< T >::run() {
      107 
      108     while (!m_stop) {
      109         m_queuestat.wait();
      110         m_queuelocker.lock();
      111         if ( m_workqueue.empty() ) {
      112             m_queuelocker.unlock();
      113             continue;
      114         }
      115         T* request = m_workqueue.front();
      116         m_workqueue.pop_front();
      117         m_queuelocker.unlock();
      118         if ( !request ) {
      119             continue;
      120         }
      121         request->process();
      122     }
      123 
      124 }
      125 
      126 #endif

       

        項目整體流程代碼實現(xiàn)

       有限狀態(tài)機

       

       

       

       EPOLLONESHOT事件

       

       服務器壓力測試

       

       

       

      參考鏈接:http://www.rzrgm.cn/logsharing/p/8448446.html

       

      posted @ 2022-03-08 18:02  白雪兒  Views(439)  Comments(0)    收藏  舉報
      主站蜘蛛池模板: 亚洲欧美日韩国产手机在线| 亚洲精品综合网二三区| 日本三线免费视频观看| 免费a级黄毛片| 国产乱人偷精品人妻a片| 亚洲V天堂V手机在线| 丁香婷婷综合激情五月色| 国产精品熟女孕妇一区二区| 无码人妻斩一区二区三区| 国产一区二区三区色噜噜| 久热这里只有精品蜜臀av| 亚洲av无码精品色午夜| 中文字幕国产精品自拍| 狠狠综合久久av一区二| 国产精品推荐手机在线| 宿州市| 俄罗斯美女真人性做爰| 亚洲中文字幕日韩精品| 欧美成人影院亚洲综合图| 亚洲天堂av免费在线看| 亚洲一国产一区二区三区| 给我播放片在线观看| 国产一区二区亚洲一区二区三区| 日本一区二区中文字幕久久| 福利视频一区二区在线| 国产福利精品一区二区| 一区二区不卡国产精品| 国产精品天天看天天狠| 四虎精品国产精品亚洲精| 亚洲精品综合网二三区| 国产香蕉97碰碰久久人人| 国产一区二区三区18禁| 国产精品视频亚洲二区| 一本大道色婷婷在线| 9久9久热精品视频在线观看| 国产不卡av一区二区| 奶头又大又白喷奶水av| 国产乱老熟女乱老熟女视频| 四虎在线中文字幕一区| 一本大道色婷婷在线| 少妇被粗大的猛烈xx动态图|