高效能伺服器程式設計感悟

2021-07-05 17:23:20 字數 1857 閱讀 1192

前些年,程式效能隨著硬體公升級而提公升往往不怎麼需要程式設計師的參與。比如cpu頻率從100m上公升到500m,原先要執行1min的程式現在可能只要執行10幾秒。而需要使用大記憶體的程式在記憶體擴容後執行速度也往往可以提高很多。但是現在情況發生了變化,想想吧。主流配置為cpu主頻2g+記憶體2g的時間已經持續了多久?太久了,現在進入了多核的時代,單核-雙核-四核。cpu也開始使用狼群戰術了。這時候如果想要提公升程式效能,就需要程式設計師付出額外的努力了:使用多程序、多執行緒,在享受快感的同時承受同步之類問題的折磨。

我個人喜歡多執行緒超過多程序,hoho,程式設計師控制線程比控制程序方便多了,共享資料也方便。所以以下討論都基於多執行緒併發。另外,雖然題目是「高效能伺服器程式設計」,但接下來講的只有併發而不包括通訊模式。ps:乙個好的伺服器架構應該較好地將通訊和業務劃分開,哪天我有空了再講通訊模式吧哈哈。

我的一些感悟:

1)不管什麼程式

模組化都很重要,對於併發程式更是如此。設想一下如果全域性變數滿天飛,執行緒安全是多麼讓人絕望的一件事。什麼是模組?我不想去google上copy軟體工程教材上的話。在我看來,《定義一》模組就是你把它實現為乙個類後在實現及修改重構時沒有感到後悔,幾年後回頭看不覺得自己sb的東東。如果程式是併發的,務必保證裡面會併發訪問到的各個模組是

執行緒安全的。

大部分模組直接使用大鎖即可。優化所有**可能引入bug(多執行緒還是挺費腦筋的),肯定浪費時間,效率未必提高多少。優化應該抓住關鍵點進行優化。但是(但是是很重要的,漢語的特點),模組的資料結構應該保證使用小鎖時不需要太多修改。具體地說:就是

資料結構中應該明確定義單元。《定義二》單元,就是增刪改查會操作到的最小單位,或者這樣乙個東西:如果你沒有把它實現為乙個類,當你想把鎖改小時會後悔。舉個例子吧,假設班級是乙個模組,提供若干個操作,班級下可以有很多學生,如果不把學生作為adt,在學生屬性不多的時候實現起來也完全ok,但是如果以後想用小鎖對乙個學生加鎖呢?方法一,用一組鎖,然後滿地找修改和讀取學生屬性的**塊進行加鎖處理,可能改得雞飛狗跳。方法二,k自己一巴掌,咋這麼笨呢,將學生概念抽取為adt,然後在這個adt裡面放乙個鎖。

3) 記得軟工裡面講模組要高內聚,

低耦合。啥叫低耦合?如果你乙個模組裡面儲存另乙個模組內資料的引用、指標甚至是陣列的某個位置。這耦合度就很高了。耦合度高時執行緒安全簡直沒法做,除非你整個程式就乙個鎖——那和單執行緒程式區別也不會很大了。所以併發程式別這麼幹。就像現在很多資料庫設計也都不用外來鍵一樣。資料可以用程式來保證邏輯關聯,但避免真實物理關聯。舉個例子,有乙個模組是班級,乙個模組是學生。比較低耦合的設計是班級中儲存這個班級學生的學號集合。高耦合的設計是班級中儲存這個班級學生的記憶體位址集合。高耦合的情況下,很多操作實現起來都會一陣雞飛狗跳。

4)要想效率高,就要

等待少。這又是廢話。就像吃多變胖喝水止渴一樣。所以關鍵是下面我要講的幾個模式,這幾個模式可以達到該目的。我可能一時想不全,以後慢慢補充吧。

a)要想富,少生孩子多種樹。咳咳,說錯了。第乙個是隨便搞模式,也就是說不鎖了,信春哥得永生,信潤哥無bug。當乙個模組都沒有提供修改操作時你鎖它幹嘛?

b)swap指標模式:先把資料準備好,鎖住,交換指標。這樣子可以大為降低鎖定持續的時間。

c)讀寫鎖模式:大部分時候,唯讀操作比寫操作要多得多,使用讀寫鎖吧!

d)趁熱模式:需要使用智慧型指標。常有這種資料結構,主體為乙個容器如vector(或者map之類),有一部分操作會增減該容器的元素,但大部分操作只是針對該容器某一元素做些**的事情,可是做**事情時我們也不得不鎖住整個容器——不然幹一半突然發現物件消失了豈不是很掃興?(如果那個服務因此掛了值班人員半夜call你真的可能掃了某方面的性質)。乙個比較好的方法是容器內儲存的是智慧型指標,第一步鎖容器,獲取該指標,解鎖,然後對這個指標想幹嘛就幹嘛。就算該元素被移出容器了,你也可以趁熱繼續嘿咻嘿咻。沒有引用計數處理記憶體釋放太麻煩了,所以要用智慧型指標。另外,容器元素應該提供執行緒安全操作。

linux高效能伺服器程式設計

linux高效能伺服器程式設計 當當網 亞馬遜 目錄 第一章 tcp ip協議族 第二章 ip協議族 第三章 tcp協議詳解 第四章 tcp ip通訊案例 訪問internet 第五章 linux網路程式設計基礎api 第六章 高階io函式 第七章 linux伺服器程式規範 第八章 高效能伺服器框架...

linux 高效能伺服器程式設計

1.高效能定時器 時間輪,時間堆 處理超時時間,如nginx使用紅黑樹,找出最可能超時的事件 2.高效能伺服器程式框架 nginx 使用的是基於事件模型,epoll,不阻塞,非同步處理 兩種高效的事件處理模式 reactor模式 proactor模式 兩種高效的併發模式 半同步 半非同步模式 領導者...

linux高效能伺服器程式設計(1)

linux網路程式設計基礎api 1 socket位址api 2 sockt基礎api sockt的api全部定義在sys socket.h檔案中,包括 建立socket,命名socket,監聽socket,接受連線,發起連線,讀寫資料,獲取位址資訊,檢測帶外標記,以及讀取和設定socket選項。3...