我應該跟libuv說聲對不起,我錯怪了libuv(轉)

来源:http://www.cnblogs.com/zhiyong-ITNote/archive/2017/06/05/6943223.html
-Advertisement-
Play Games

一開始,我得向Libuv庫和Libuv庫開發者以及相關粉絲們道一個歉,對不起,我錯怪你們了。深深感到自己的無知,是多麼羞愧的事情!! 事情的經過是這樣的。 原先按照公司要求,我在開發Windows版的TCP伺服器時,使用了Libuv庫。正是因為Libuv庫的強大,才讓我們老大推薦使用。我們老大學識淵 ...


一開始,我得向Libuv庫和Libuv庫開發者以及相關粉絲們道一個歉,對不起,我錯怪你們了。深深感到自己的無知,是多麼羞愧的事情!!
    事情的經過是這樣的。
    原先按照公司要求,我在開發Windows版的TCP伺服器時,使用了Libuv庫。正是因為Libuv庫的強大,才讓我們老大推薦使用。我們老大學識淵博,閱歷豐富,他的推薦自然也是很值得使用的。所以我快速學習了一下Libuv庫的使用。然後再學習的過程中,稍有瞭解。同時發現了一個網友phata寫的對於Libuv庫的包裝,讓代碼寫起來更加方便。當然,他是針對Windows版的包裝。我用了之後,也就大大加快了開發的速度。對此,我非常感謝網友phata。也正是這些網友的無私,將一些寶貴的代碼分享出來,才促進了開發的發展,讓學習開發變得容易。所以我一直堅持分享的習慣,也正是更多是受益於各路網友的分享,我學有所成,我也希望將我的經驗和成果分享給更多人。互聯網的共用互助精神大概如此吧。C++技術網就是我分享我所有經驗的平臺,希望更多人能夠參與進來吧。
    Windows版的伺服器做好之後,後來又需要Linux版的伺服器。所以,直接將libuv使用在了Linux的Centos發行版上了。phata編寫的Windows版本libuv封裝類,我進行了精簡整理,發佈在C++技術網。然後我再將這個精簡後的版本,改成了Linux版本,並應用在了Linux版的伺服器上。Linux版的Libuv封裝類的代碼見《基於libuv封裝的TCP通信類-服務端類源代碼》。在這個文章里,你可以找到其他相關的代碼。
    然而好景不長,在後續的測試中發現了一個問題:客戶端發送一個數據到伺服器後,伺服器單次回覆一次數據,一切正常。但是收到一個數據,連續回覆兩次數據時,不管是間隔1秒還是10秒,都會造成線程死迴圈。這個問題持續了很久,而且只在Linux中表現出來。
    遲遲沒有直接解決問題,所以後來就想到一個辦法,就是將多個數據合併到一個數據,然後將多次發送做成了一次發送,這樣就避開了問題。然而再後來出現的需求,讓合併數據成為了不可能。兩次發送數據,是兩個線程完成的。但是有時候可能合併得到一起,有時候無法合併到一起,因為我還是想利用之前避開問題的方法來實現,結果效果很不理想。
    所以,在最開始出現連續兩次發送數據造成死迴圈的時候,我將我上層的業務代碼全部幹掉,直接寫測試代碼,結果發現一樣會出現死迴圈。這樣之後,我就認定是Libuv的坑了。所以後來就只有饒坑了,心情很是不爽。
    按照其他同事的說法,Libuv是nodejs使用的,應該不會出現這麼低級的問題吧。其實我也覺得不應該出現這麼低級的問題,然而這個問題就在這,我都不知道為什麼。只能先將鍋甩給了libuv。
    當後面的需求,無法繞過去的時候,還是要直接面對這個坑的問題。怎麼辦呢?那就只能學習和深入研究源碼了。最要命的是,Libuv的資料太少了,就有那麼一本英文書,網路有人正在翻譯為中文,還沒有翻譯完。而且這個書也不是那麼全面,至少我讀了之後,還是沒有完全明白的意思,懵懵懂懂的。除了這個,基本上沒有比較深入的資料了。要麼是一點學習筆記,寫了一個demo,無關痛癢。
    正是因為Libuv文檔太少了,讓學習Libuv變得困難,出現問題都無從查詢資料。而源碼,也不是誰都能夠看懂的。我也不願意去鑽研源碼,如果能夠解決問題,絕不研究源碼。如果是對源碼本身感興趣,那也是閑暇的時候研究,而工作比較緊張,沒有那麼多時間。
    事情已經進行到了必須面對問題的時候,所以我就開始再從僅有的少數資料里和代碼里研究問題。然後也加了一個QQ群,群也就3個。對於示例代碼的一個簡單的問題,一個群友竟然說要500RMB才肯解答,說他研究了2年了。哎~ 我自己繼續研究好了。

        然後不斷的調試代碼,分析代碼的流程,這次是直接使用libuv的測試代碼研究,通過熟悉代碼,測試,然後竟然成功的實現了連續兩次伺服器回覆命令。2017年6月3日上午,實現了一個版本。然後晚上,又實現了另外一個版本。第一個版本比較湊合,第二個版本最接近於我使用的版本,也就是前面提到的改成Linux下的libuv包裝類,其實和示例代碼差不多。在這個示例測試中,直接連續兩次發送數據,和項目中的問題一樣。然後通過不懈的努力,然後成功實現了連續兩次發送數據,依然正常運行。

    我應該跟libuv說聲對不起,我錯怪了libuv

    到現在為止,我才真正明白我之前的問題所在了。問題不在libuv,也不在於網友phata的Windows版的libuv包裝類,而是在於我改成linux版的libuv包裝類。我忽略的一點就是,libuv在Windows上使用的是完成埠,而在linux上使用的是非同步事件epoll。兩者是不一樣的,所以在改成linux版libuv包裝類的時候,我沒有做好處理,只是簡單的改了一下,忽略了底層實現的差異,才出現了這個問題。所以在Windows上沒有問題,在Linux有問題。我竟然直接根據這個判定libuv有這樣一個低級的坑!可見我是多麼無知。
    所以我總結一句話:完全相信權威,那是迷信;而不深入調查,僅根據表明現象就直接否定權威,那是無知!!
    我們經常聽說不要完全相信權威,要敢於質疑權威,但是很多時候,我們卻不知道,質疑權威應該如何質疑。正確的質疑是用實踐去證明,用合理的證據證明權威是錯的。而我這個行為,是沒有經過深入的調查研究的,所以是無知的表現。還好,有這機會讓我直接面對問題,讓我查出問題的原因,讓我反省,讓我矯正自己的態度。

        寫下這篇文章,記錄一下此時我的無知,在今後的研究路上,多一份謙遜,多一份研究,少一點無知,也用以警告我自己,不要隨意下定論。

        註:Linux版本的libuv包裝類,你還是可以使用的,只是不要對一個請求回覆多個命令。一對一的回覆,這個包裝類是可以用的。後面我再想辦法改進,修複這個問題。所以分享的那個代碼是可以用,只是要註意這個問題。

原文鏈接


您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • 一.介紹 二.服務端配置 1.關閉系統防火牆和selinux 查看系統防火牆的狀態,可以看到防火牆是開著的 [root@bogon ~] systemctl status firewalld ● firewalld.service firewalld dynamic firewall daemon ...
  • . NET Core 從2016年6月28日發佈,過去了將近一年的時間,但是在工作中發現大家對.net core的接受程度並不高,這隻是一個感覺,俗話說“沒有調查就沒有發言權”, 這兩天通過微信小程式在微信群里做了一個調查,參與的人數大概230人,從結果看大家都在等待.NET Core 2.0, 期 ...
  • 淺談orm 記得四年前在學校第一次接觸到 Ling to Sql,那時候瞬間發現不用手寫sql語句是多麼的方便,後面慢慢的接觸了許多orm框架,像 EF,Dapper,Hibernate,ServiceStack.OrmLite 等。當然每種orm都有各自的優勢,也有不足的地方。園子里也有很多大神開 ...
  • python2.7的編碼格式不再是ASCII碼,直接就是UTF-8. 導入sys模塊,通過getdefaultencoding方法可以查看編碼格式。 因此,python2.7解決中文字元的編碼問題可以直接聲明編碼格式,不再通過麻煩的decode和encode進行轉換。 此處仍然需要在中文字元前加入u ...
  • 網上商城實戰3 今日任務 完成購物模塊的功能 完成訂單模塊的功能 1.1 購物模塊: 1.1.1 功能演示: 商品詳情: 購物車模塊: 1.1.2 代碼實現: 1.在商品詳情的頁面中點擊【加入購物車】鏈及. 2.提交到Servlet中: * 提交購買的商品的數量. * 提交購買的商品的ID. 3.將 ...
  • 一、後臺日期類型解析到前端 1.在springmvc的配置文件中添加這個.annotation-driven在配置文件中只配置一次 (此方法全局作用)<mvc:annotation-driven> <mvc:message-converters> <bean class="org.springfra ...
  • 原創聲明:本文為本人原創作品,絕非他處摘取,轉載請聯繫博主 相信大家在各大網站都會遇到,登錄時,在登錄框出現下次免登陸/一個月免登陸的類似選項,本次博文就是講解如何實現,在這記錄一下,也算是做個備忘錄合集,如果文中有錯,歡迎大家指出 為啥說自登陸一次呢,因為當訪問某個頁面時,如果第一次自動登錄失敗時 ...
  • 序列標註(sequence labelling),輸入序列每一幀預測一個類別。OCR(Optical Character Recognition 光學字元識別)。 MIT口語系統研究組Rob Kassel收集,斯坦福大學人工智慧實驗室Ben Taskar預處理OCR數據集(http://ai.sta ...
一周排行
    -Advertisement-
    Play Games
  • 移動開發(一):使用.NET MAUI開發第一個安卓APP 對於工作多年的C#程式員來說,近來想嘗試開發一款安卓APP,考慮了很久最終選擇使用.NET MAUI這個微軟官方的框架來嘗試體驗開發安卓APP,畢竟是使用Visual Studio開發工具,使用起來也比較的順手,結合微軟官方的教程進行了安卓 ...
  • 前言 QuestPDF 是一個開源 .NET 庫,用於生成 PDF 文檔。使用了C# Fluent API方式可簡化開發、減少錯誤並提高工作效率。利用它可以輕鬆生成 PDF 報告、發票、導出文件等。 項目介紹 QuestPDF 是一個革命性的開源 .NET 庫,它徹底改變了我們生成 PDF 文檔的方 ...
  • 項目地址 項目後端地址: https://github.com/ZyPLJ/ZYTteeHole 項目前端頁面地址: ZyPLJ/TreeHoleVue (github.com) https://github.com/ZyPLJ/TreeHoleVue 目前項目測試訪問地址: http://tree ...
  • 話不多說,直接開乾 一.下載 1.官方鏈接下載: https://www.microsoft.com/zh-cn/sql-server/sql-server-downloads 2.在下載目錄中找到下麵這個小的安裝包 SQL2022-SSEI-Dev.exe,運行開始下載SQL server; 二. ...
  • 前言 隨著物聯網(IoT)技術的迅猛發展,MQTT(消息隊列遙測傳輸)協議憑藉其輕量級和高效性,已成為眾多物聯網應用的首選通信標準。 MQTTnet 作為一個高性能的 .NET 開源庫,為 .NET 平臺上的 MQTT 客戶端與伺服器開發提供了強大的支持。 本文將全面介紹 MQTTnet 的核心功能 ...
  • Serilog支持多種接收器用於日誌存儲,增強器用於添加屬性,LogContext管理動態屬性,支持多種輸出格式包括純文本、JSON及ExpressionTemplate。還提供了自定義格式化選項,適用於不同需求。 ...
  • 目錄簡介獲取 HTML 文檔解析 HTML 文檔測試參考文章 簡介 動態內容網站使用 JavaScript 腳本動態檢索和渲染數據,爬取信息時需要模擬瀏覽器行為,否則獲取到的源碼基本是空的。 本文使用的爬取步驟如下: 使用 Selenium 獲取渲染後的 HTML 文檔 使用 HtmlAgility ...
  • 1.前言 什麼是熱更新 游戲或者軟體更新時,無需重新下載客戶端進行安裝,而是在應用程式啟動的情況下,在內部進行資源或者代碼更新 Unity目前常用熱更新解決方案 HybridCLR,Xlua,ILRuntime等 Unity目前常用資源管理解決方案 AssetBundles,Addressable, ...
  • 本文章主要是在C# ASP.NET Core Web API框架實現向手機發送驗證碼簡訊功能。這裡我選擇是一個互億無線簡訊驗證碼平臺,其實像阿裡雲,騰訊雲上面也可以。 首先我們先去 互億無線 https://www.ihuyi.com/api/sms.html 去註冊一個賬號 註冊完成賬號後,它會送 ...
  • 通過以下方式可以高效,並保證數據同步的可靠性 1.API設計 使用RESTful設計,確保API端點明確,並使用適當的HTTP方法(如POST用於創建,PUT用於更新)。 設計清晰的請求和響應模型,以確保客戶端能夠理解預期格式。 2.數據驗證 在伺服器端進行嚴格的數據驗證,確保接收到的數據符合預期格 ...