锘??xml version="1.0" encoding="utf-8" standalone="yes"?>在线播放日韩,极品中文字幕一区,久久久精品国产免费观看同学http://m.shnenglu.com/kevinlynx/浣庤皟鍋氭妧鏈痏_嬈㈣繋縐繪鎴戠殑鐙珛鍗氬 <a >codemaro.com</a> 寰崥 <a >kevinlynx</a>zh-cnTue, 21 Oct 2025 20:24:49 GMTTue, 21 Oct 2025 20:24:49 GMT60鍐欎簡(jiǎn)涓涓垎甯冨紡鍚嶅瓧鏈嶅姟JCMhttp://m.shnenglu.com/kevinlynx/archive/2015/07/04/211145.htmlKevin LynxKevin LynxSat, 04 Jul 2015 09:50:00 GMThttp://m.shnenglu.com/kevinlynx/archive/2015/07/04/211145.htmlhttp://m.shnenglu.com/kevinlynx/comments/211145.htmlhttp://m.shnenglu.com/kevinlynx/archive/2015/07/04/211145.html#Feedback0http://m.shnenglu.com/kevinlynx/comments/commentRss/211145.htmlhttp://m.shnenglu.com/kevinlynx/services/trackbacks/211145.html

涔嬪墠鍦ㄥ叕鍙擱噷緇存姢浜?jiǎn)涓涓悕瀛楁湇鍔★紝榪欎釜鍚嶅瓧鏈嶅姟鏃ュ父綆$悊浜?jiǎn)杩?000鍙版満鍣紝鏈?000涓乏鍙崇殑瀹㈡埛绔繛鎺ヤ笂鏉ヨ幏鍙栨満鍣ㄤ俊鎭紝鐢變簬鍏跺熀鏈槸涓涓崟鐐規(guī)湇鍔★紝鎵浠ユ煇浜涙ā鍧楁帴榪戠摱棰堛傚悗鏉ュ掓槸鏈夐噸鏋勮鍒掞紝璇︾粏璁捐鍋氫簡(jiǎn)錛屼唬鐮侀兘鍐欎簡(jiǎn)涓閮ㄥ垎錛岀粨鏋滅敱浜庢煇浜涘師鍥犻噸鏋勫氨琚粓姝簡(jiǎn)銆?/p>

JCM鏄垜涓氫綑鏃墮棿鐢↗ava閲嶅啓鐨勪竴涓増鏈紝鍔熻兘涓婄洰鍓嶅彧瀹炵幇浜?jiǎn)鍩杭媭鍔熻兘銆傜敱浜庡畠鏄釜瀹屽叏鍒嗗竷寮忕殑鏋舵瀯錛屾墍浠ョ悊璁轟笂鍙互妯悜鎵╁睍錛屽ぇ澶у寮虹郴緇熺殑鏈嶅姟鑳藉姏銆?/p>

鍚嶅瓧鏈嶅姟

鍦ㄥ垎甯冨紡緋葷粺涓紝鏌愪釜鏈嶅姟涓轟簡(jiǎn)鎻愬崌鏁翠綋鏈嶅姟鑳藉姏錛岄氬父閮ㄧ講浜?jiǎn)寰堝瀹炰緥銆傝繖閲屾垜鎶婅繖浜涙彁渚涚浉鍚屾湇鍔$殑瀹炰緥緇熺О涓洪泦緹?cluster)錛屾瘡涓疄渚嬬О涓轟竴涓妭鐐?Node)銆備竴涓簲鐢ㄥ彲鑳戒細(xì)浣跨敤寰堝cluster錛屾瘡嬈¤闂竴涓猚luster鏃訛紝灝遍氳繃鍚嶅瓧鏈嶅姟鑾峰彇璇luster涓嬩竴涓彲鐢ㄧ殑node銆傞偅涔堬紝鍚嶅瓧鏈嶅姟鑷沖皯闇瑕佸寘鍚殑鍔熻兘錛?/p>

  • 鏍規(guī)嵁cluster鍚嶅瓧鑾峰彇鍙敤鐨刵ode
  • 瀵圭鐞嗙殑鎵鏈塩luster涓嬬殑鎵鏈塶ode榪涜鍋ュ悍搴︾殑媯(gè)嫻嬶紝浠ヤ繚璇佸緇堣繑鍥炲彲鐢ㄧ殑node

鏈変簺鍚嶅瓧鏈嶅姟浠呭node綆$悊錛屼笉鍙備笌搴旂敤涓巒ode闂寸殑閫氫俊錛岃屾湁浜涘垯鍙兘浣滀負(fù)搴旂敤涓巒ode闂寸殑閫氫俊杞彂鍣ㄣ傝櫧鐒跺悕瀛楁湇鍔″姛鑳界畝鍗曪紝浣嗘槸瑕佸仛涓涓垎甯冨紡鐨勫悕瀛楁湇鍔¤繕鏄瘮杈冨鏉傜殑錛屽洜涓烘暟鎹竴鏃﹀垎甯冨紡浜?jiǎn)锛尀兗?xì)瀛樺湪鍚屾銆佷竴鑷存ч棶棰樼殑鑰冭檻絳夈?/p>

What鈥檚 JCM

JCM鍥寸粫鍓嶉潰璇寸殑鍚嶅瓧鏈嶅姟鍩虹鍔熻兘瀹炵幇銆傚寘鍚殑鍔熻兘錛?/p>

  • 綆$悊cluster鍒皀ode鐨勬槧灝?/li>
  • 鍒嗗竷寮忔灦鏋勶紝鍙按騫蟲(chóng)墿灞曚互瀹炵幇綆$悊10,000涓猲ode鐨勮兘鍔涳紝瓚充互綆$悊涓鑸叕鍙哥殑鍚庡彴鏈嶅姟闆嗙兢
  • 瀵規(guī)瘡涓猲ode榪涜鍋ュ悍媯(gè)鏌ワ紝鍋ュ悍媯(gè)鏌ュ彲鍩轟簬HTTP鍗忚灞傜殑媯(gè)嫻嬫垨TCP榪炴帴媯(gè)嫻?/li>
  • 鎸佷箙鍖朿luster/node鏁版嵁錛岄氳繃zookeeper淇濊瘉鏁版嵁涓鑷存?/li>
  • 鎻愪緵JSON HTTP API綆$悊cluster/node鏁版嵁錛屽悗緇彲鎻愪緵Web綆$悊緋葷粺
  • 浠ュ簱鐨勫艦寮忔彁渚涗笌server鐨勪氦浜掞紝搴撴湰韜彁渚涘悇縐嶈礋杞藉潎琛$瓥鐣ワ紝淇濊瘉瀵逛竴涓猚luster涓媙ode鐨勮闂揪鍒拌礋杞藉潎琛?/li>

欏圭洰鍦板潃git jcm

JCM涓昏鍖呭惈涓ら儴鍒嗭細(xì)

  • jcm.server錛孞CM鍚嶅瓧鏈嶅姟錛岄渶瑕佽繛鎺ookeeper浠ユ寔涔呭寲鏁版嵁
  • jcm.subscriber錛屽鎴風(fēng)搴擄紝璐熻矗涓巎cm.server浜や簰錛屾彁渚涘寘瑁呬簡(jiǎn)璐熻澆鍧囪 鐨凙PI緇欏簲鐢ㄤ嬌鐢?/li>

鏋舵瀯

鍩轟簬JCM鐨勭郴緇熸暣浣撴灦鏋勫涓嬶細(xì)

simple-arch.jpg

cluster鏈韓鏄笉闇瑕佷緷璧朖CM鐨勶紝瑕侀氳繃JCM浣跨敤榪欎簺cluster錛屽彧闇瑕侀氳繃JCM HTTP API娉ㄥ唽榪欎簺cluster鍒癹cm.server涓娿傝閫氳繃jcm.server浣跨敤榪欎簺cluster錛屽垯鏄氳繃jcm.subscriber鏉ュ畬鎴愩?/p>

浣跨敤

鍙弬鑰?a >git READMe.md

闇瑕乯re1.7+

  1. 鍚姩zookeeper
  2. 涓嬭澆jcm.server git jcm.server-0.1.0.jar
  3. 鍦?code>jcm.server-0.1.0.jar鐩綍涓嬪緩绔?code>config/application.properties鏂囦歡榪涜閰嶇疆錛屽弬鑰?a >config/application.properties
  4. 鍚姩jcm.server

     java -jar jcm.server-0.1.0.jar
    
  5. 娉ㄥ唽闇瑕佺鐞嗙殑闆嗙兢錛屽弬鑰僣luster鎻忚堪錛?a >doc/cluster_sample.json錛岄氳繃HTTP API娉ㄥ唽錛?/p>

     curl -i -X POST http://10.181.97.106:8080/c -H "Content-Type:application/json" --data-binary @./doc/cluster_sample.json
    

閮ㄧ講濂戒簡(jiǎn)jcm.server錛屽茍娉ㄥ唽浜?jiǎn)cluster鍚庯紝灝卞彲浠ラ氳繃jcm.subscriber浣跨敤錛?/p>

// 浼犲叆闇瑕佷嬌鐢ㄧ殑闆嗙兢鍚峢ello9/hello錛屼互鍙?qiáng)浼犲叆jcm.server鍦板潃錛屽彲浠ュ涓細(xì)127.0.0.1:8080
Subscriber subscriber = new Subscriber( Arrays.asList("127.0.0.1:8080"), Arrays.asList("hello9", "hello"));
// 浣跨敤杞璐熻澆鍧囪 絳栫暐
RRAllocator rr = new RRAllocator();
subscriber.addListener(rr);
subscriber.startup();
for (int i = 0; i < 2; ++i) {
  // rr.alloc 鏍規(guī)嵁cluster鍚嶅瓧鑾峰彇鍙敤鐨刵ode
  System.out.println(rr.alloc("hello9", ProtoType.HTTP));
}
subscriber.shutdown();

JCM瀹炵幇

JCM鐩墠鐨勫疄鐜版瘮杈冪畝鍗曪紝鍙傝冩ā鍧楀浘錛?/p>

impl-module

  • model錛屽嵆cluster/node榪欎簺鏁版嵁緇撴瀯鐨勬弿榪幫紝鍚屾椂琚玧cm.server鍜宩cm.subscriber渚濊禆
  • storage錛屾寔涔呭寲鏁版嵁鍒皕ookeeper錛屽悓鏃跺寘鍚玧cm.server瀹炰緥涔嬮棿鐨勬暟鎹悓姝?/li>
  • health check錛屽仴搴鋒鏌ユā鍧楋紝瀵瑰悇涓猲ode榪涜鍋ュ悍媯(gè)鏌?/li>

浠ヤ笂妯″潡閮戒笉渚濊禆Spring錛屽熀浜庝互涓婃ā鍧楀張鏈夛細(xì)

  • http api錛屼嬌鐢╯pring-mvc錛屽寘瑁呬簡(jiǎn)涓浜汮SON HTTP API
  • Application錛屽熀浜巗pring-boot錛屽皢鍚勪釜鍩虹妯″潡緇勮璧鋒潵錛屾彁渚泂tandalone鐨勬ā寮忓惎鍔紝涓嶇敤閮ㄧ講鍒皌omcat涔嬬被鐨剆ervlet瀹瑰櫒涓?/li>

jcm.subscriber鐨勫疄鐜版洿綆鍗曪紝涓昏鏄礋璐d笌jcm.server榪涜閫氫俊錛屼互鏇存柊鑷繁褰撳墠鐨刴odel灞傛暟鎹紝鍚屾椂鎻愪緵鍚勭璐熻澆鍧囪 絳栫暐鎺ュ彛錛?/p>

  • subscriber錛屼笌jcm.server閫氫俊錛屽畾鏈熷閲忔媺鍙栨暟鎹?/li>
  • node allocator錛岄氳繃listener鏂瑰紡浠巗ubscriber涓幏鍙栨暟鎹紝鍚屾椂瀹炵幇鍚勭璐熻澆鍧囪 絳栫暐錛屽澶栫粺涓鎻愪緵alloc node鐨勬帴鍙?/li>

鎺ヤ笅鏉ョ湅鐪嬪叧閿姛鑳界殑瀹炵幇

鏁版嵁鍚屾

鏃㈢劧jcm.server鏄垎甯冨紡鐨勶紝姣忎竴涓猨cm.server instance(瀹炰緥)閮芥槸鏀寔鏁版嵁璇誨拰鍐欑殑錛岄偅涔堝綋jcm.server綆$悊鐫涓鍫哻luster涓婁竾涓猲ode鏃訛紝姣忎竴涓猧nstance鏄浣曡繘琛屾暟鎹悓姝ョ殑錛焜cm.server涓殑鏁版嵁涓昏鏈変袱綾伙細(xì)

  • cluster鏈韓鐨勬暟鎹紝鍖呮嫭cluster/node鐨勬弿榪幫紝渚嬪cluster name銆乶ode IP銆佸強(qiáng)鍏朵粬闄勫睘鏁版嵁
  • node鍋ュ悍媯(gè)鏌ョ殑鏁版嵁

瀵逛簬cluster鏁版嵁錛屽洜涓篶luster瀵筺ode鐨勭鐞嗘槸涓涓袱灞傜殑鏍?wèi)鐘毒l撴瀯錛岃屽cluster鏈夊鍒爊ode鐨勬搷浣滐紝鎵浠ュ茍涓嶈兘鍦ㄦ瘡涓涓猧nstance涓婇兘鎻愪緵鐪熸鐨勬暟鎹啓鍏ワ紝榪欐牱浼?xì)瀵艰嚧鏁版嵁涓㈠け銆傚亣璁懼悓涓鏃跺埢鍦╥nstance A鍜宨nstance B涓婂悓鏃跺cluster c1娣誨姞鑺傜偣N1鍜孨2錛岄偅涔坕nstance A鍐欏叆c1(N1)錛岃宨nstance B榪樻病絳夊埌鏁版嵁鍚屾灝卞啓鍏1(N2)錛岄偅涔坈1(N1)灝辮瑕嗙洊涓篶1(N2)錛屼粠鑰屽鑷存坊鍔犵殑鑺傜偣N1涓㈠け銆?/p>

鎵浠ワ紝jcm.server instance鏄垎涓?code>leader鍜?code>follower鐨勶紝鐪熸鐨勫啓鍏ユ搷浣滃彧鏈塴eader榪涜錛宖ollower鏀跺埌鍐欐搷浣滆姹傛椂杞彂緇檒eader銆俵eader鍐欐暟鎹紭鍏堟洿鏂板唴瀛樹(shù)腑鐨勬暟鎹啀鍐欏叆zookeeper錛屽唴瀛樹(shù)腑鐨勬暟鎹洿鏂板綋鐒舵槸闇瑕佸姞閿佷簰鏂ョ殑錛屼粠鑰屼繚璇佹暟鎹殑姝g‘鎬с?/p>

write-watch.jpg

leader鍜宖ollower鏄浣曠‘瀹氳鑹茬殑錛熻繖涓緢綆鍗曪紝鏍囧噯鐨勫埄鐢▃ookeeper鏉ヨ繘琛屼富浠?a >閫変婦鐨勫疄鐜?/a>銆?/p>

jcm.server instance鏁版嵁闂寸殑鍚屾鏄熀浜巣ookeeper watch鏈哄埗鐨勩傝繖涓彲浠ョ畻鍋氭槸涓涓狫CM鐨勪竴涓摱棰堬紝姣忎竴涓猧nstance閮戒細(xì)浣滀負(fù)涓涓獁atch錛屼嬌寰楀疄闄呬笂jcm.server騫朵笉鑳芥棤闄愭按騫蟲(chóng)墿灞曪紝鎵╁睍鍒頒竴瀹氱▼搴﹀悗錛寃atch鐨勬晥鐜囧氨鍙兘涓嶈凍浠ユ弧瓚蟲(chóng)ц兘浜?jiǎn)锛屽弬鑰?a >zookeeper鑺傜偣鏁頒笌watch鐨勬ц兘嫻嬭瘯 (閭d釜鏃跺欐垜灝卞湪鑰冭檻瀵規(guī)垜浠郴緇熺殑閲嶆瀯浜? 銆?/p>

jcm.server涓node鍋ュ悍媯(gè)鏌ョ殑鏁版嵁閲囩敤鍚屾牱鐨勫悓姝ユ満鍒訛紝浣唍ode鍋ュ悍媯(gè)鏌ユ暟鎹槸姣忎竴涓猧nstance閮戒細(xì)鍐欏叆鐨勶紝涓嬮潰鐪嬬湅jcm.server鏄浣曢氳繃鍒嗗竷寮忔灦鏋勬潵鍒嗘媴鍘嬪姏鐨勩?/p>

鍋ュ悍媯(gè)鏌?/h3>

jcm.server鐨勫彟涓涓富瑕佸姛鑳界殑鏄node鐨勫仴搴鋒鏌ワ紝jcm.server闆嗙兢鍙互綆$悊鍑犱竾鐨刵ode錛屾棦鐒跺凡緇忔槸鍒嗗竷寮忎簡(jiǎn)錛岄偅涔堟樉鐒舵槸瑕佹妸node鍧囧垎鍒板涓猧nstance鐨勩傝繖閲屾垜鏄互cluster鏉ュ垎閰嶇殑錛屾柟娉曞氨鏄畝鍗曠殑浣跨敤涓鑷存у搱甯屻傞氳繃涓鑷存у搱甯岋紝鍐沖畾涓涓猚luster鏄惁灞炰簬鏌愪釜instance璐熻矗銆傛瘡涓猧nstance閮芥湁涓涓猻erver spec錛屼篃灝辨槸璇nstance瀵瑰鎻愪緵鏈嶅姟鐨勫湴鍧(IP+port)錛岃繖鏍峰湪浠諱綍涓涓猧nstance涓婏紝瀹冪湅鍒扮殑鎵鏈塱nstance server spec閮芥槸鐩稿悓鐨勶紝浠庤屼繚璇佸湪姣忎竴涓猧nstance涓婅綆梒luster鐨勫垎閰嶅緱鍒扮殑緇撴灉閮芥槸涓鑷寸殑銆?/p>

鍋ュ悍媯(gè)鏌ユ寜cluster鍒掑垎錛屽彲浠ョ畝鍖栨暟鎹殑鍐欏啿紿侀棶棰橈紝鍦ㄦ甯告儏鍐典笅錛屾瘡涓猧nstance鍐欏叆鐨勫仴搴鋒鏌ョ粨鏋滈兘鏄笉鍚岀殑銆?/p>

health-check.jpg

鍋ュ悍媯(gè)鏌ヤ竴鑸互1縐掔殑棰戠巼榪涜錛宩cm.server鍋氫簡(jiǎn)浼樺寲錛屽綋媯(gè)鏌ョ粨鏋滃拰涓婁竴嬈′竴鏍鋒椂錛屽茍涓嶅啓鍏ookeeper銆傚啓鍏ョ殑鏁版嵁鍖呭惈浜?jiǎn)node鐨勫畬鏁磌ey (IP+Port+Spec)錛岃繖鏍峰彲浠ョ畝鍖栧緢澶氬湴鏂圭殑鏁版嵁鍚屾闂錛屼絾浼?xì)澧炲姞鍐欏叆鏁版嵁鐨勫ぇ灏忓Q屽啓鍏ユ暟鎹殑澶у皬鏄細(xì)褰卞搷zookeeper鐨勬ц兘鐨勶紝鎵浠ヨ繖閲岀畝鍗曞湴瀵規(guī)暟鎹繘琛屼簡(jiǎn)鍘嬬緝銆?/p>

鍋ュ悍媯(gè)鏌ユ槸鍙互鏀寔澶氱媯(gè)鏌ュ疄鐜扮殑錛岀洰鍓嶅彧瀹炵幇浜?jiǎn)HTTP鍗忚灞傜殑媯(gè)鏌ャ傚仴搴鋒鏌ヨ嚜韜槸鍗曚釜綰跨▼錛屽湪璇ョ嚎紼嬩腑鍩轟簬寮傛HTTP搴擄紝鍙戣搗寮傛璇鋒眰錛屽疄闄呯殑璇鋒眰鍦ㄥ叾浠栫嚎紼嬩腑鍙戝嚭銆?/p>

jcm.subscriber閫氫俊

jcm.subscriber涓巎cm.server閫氫俊錛屼富瑕佹槸涓轟簡(jiǎn)鑾峰彇鏈鏂扮殑cluster鏁版嵁銆俿ubscriber鍒濆鍖栨椂浼?xì)鎷垮堫C竴涓猨cm.server instance鐨勫湴鍧鍒楄〃錛岃闂椂浣跨敤杞絳栫暐浠ュ鉤琛cm.server鍦ㄥ鐞嗚姹傛椂鐨勮礋杞姐俿ubscriber姣忕閮戒細(xì)璇鋒眰涓嬈℃暟鎹紝璇鋒眰涓弿榪頒簡(jiǎn)鏈璇鋒眰鎯寵幏鍙栧摢浜沜luster鏁版嵁錛屽悓鏃舵惡甯︿竴涓猚luster鐨剉ersion銆傛瘡嬈luster鍦╯erver鍙樻洿鏃訛紝version灝卞彉鏇達(dá)紙鏃墮棿鎴籌級(jí)銆俿erver鍥炲璇鋒眰鏃訛紝濡傛灉version宸叉渶鏂幫紝鍙渶瑕佸洖澶峮ode鐨勭姸鎬併?/p>

subscriber鍙互鎷垮埌鎵鏈夌姸鎬佺殑node錛屽悗闈㈠彲浠ヨ冭檻鍙嬁姝e父鐘舵佺殑node錛岃繘涓姝ュ噺灝戞暟鎹ぇ灝忋?/p>

鍘嬪姏嫻嬭瘯

鐩墠鍙鍋ュ悍媯(gè)鏌ラ儴鍒嗗仛浜?jiǎn)鍘媼箣锛岃缁嗗弬鑰?a >test/benchmark.md銆傚湪A7鏈嶅姟鍣ㄤ笂嫻嬭瘯錛屽彂鐜板啓zookeeper鍙?qiáng)zookeeper鐨剋atch瓚充互婊¤凍瑕佹眰錛宩cm.server鍙戣搗鐨凥TTP璇鋒眰鏄富瑕佺殑鎬ц兘鐑偣錛屽崟jcm.server instance澶ф鍙互鎵胯澆20000涓猲ode鐨勫仴搴風(fēng)洃嫻嬨?/p>

緗戠粶甯﹀錛?/p>

1
2
3
4
5
Time              ---------------------traffic--------------------
Time               bytin  bytout   pktin  pktout  pkterr  pktdrp
01/07/15-21:30:48   3.2M    4.1M   33.5K   34.4K    0.00    0.00
01/07/15-21:30:50   3.3M    4.2M   33.7K   35.9K    0.00    0.00
01/07/15-21:30:52   2.8M    4.1M   32.6K   41.6K    0.00    0.00

CPU錛岄氳繃jstack鏌ョ湅涓昏鐨凜PU娑堣楀湪HTTP搴撳疄鐜板眰錛屼互鍙?qiáng)鍋ュ轰h鏌ョ嚎紼嬶細(xì)

1
2
3
4
  PID USER      PR  NI  VIRT  RES  SHR S %CPU %MEM    TIME+  COMMAND
13301 admin     20   0 13.1g 1.1g  12m R 76.6  2.3   2:40.74 java         httpchecker
13300 admin     20   0 13.1g 1.1g  12m S 72.9  2.3   0:48.31 java
13275 admin     20   0 13.1g 1.1g  12m S 20.1  2.3   0:18.49 java

浠g爜涓鍔犱簡(jiǎn)浜涚姸鎬佺洃鎺э細(xì)

1
checker HttpChecker stat count 20 avg check cost(ms) 542.05, avg flush cost(ms) 41.35

琛ㄧず騫沖潎姣忔媯(gè)鏌ヨ楁椂542姣錛屽啓鏁版嵁鍥犱負(fù)寮鍚簡(jiǎn)cache娌℃湁鍙傝冧環(huán)鍊箋?/p>

铏界劧榪樺彲浠ヤ粠鎴戣嚜宸辯殑浠g爜涓仛涓嶅皯浼樺寲錛屼絾鏃㈢劧鍗曟満鍙互鎵胯澆20000涓妭鐐圭殑媯(gè)嫻嬶紝涓鑸殑搴旂敤榪滆繙瓚沖浜?jiǎn)銆?/p>

鎬葷粨

鍚嶅瓧鏈嶅姟鍦ㄥ垎甯冨紡緋葷粺涓櫧鐒舵槸鍩虹鏈嶅姟錛屼絾寰寰鎵挎媴浜?jiǎn)闈炲笖R噸瑕佺殑瑙掕壊錛屾暟鎹悓姝ュ嚭鐜伴敊璇佽妭鐐圭姸鎬佸嚭鐜扮灛鏃剁殑閿欒錛岄兘鍙兘瀵規(guī)暣濂楃郴緇熼犳垚杈冨ぇ褰卞搷錛屼笟鍔′笂鍑虹幇杈冨ぇ鏁呴殰銆傛墍浠ュ悕瀛楁湇鍔$殑鍋ュ.鎬с佸彲鐢ㄦч潪甯擱噸瑕併傚疄鐜頒腑闇瑕佽冭檻寰堝寮傚父鎯呭喌錛屽寘鎷綉緇滀笉紼沖畾銆佸簲鐢ㄥ眰鐨勯敊璇瓑銆備負(fù)浜?jiǎn)鎻愰珮鑳鲥鐨勫彲鐢ㄦэ紝涓鑸繕?shù)細(xì)鍔犲灞傜殑鏁版嵁cache錛屼緥濡俿ubscriber绔殑鏈湴cache錛宻erver绔殑鏈湴cache錛屼互淇濊瘉鍦ㄤ換浣曟儏鍐典笅閮戒笉浼?xì)濯?jiǎng)鍝嶅簲鐢ㄥ眰鐨勬湇鍔°?/p>



Kevin Lynx 2015-07-04 17:50 鍙戣〃璇勮
]]>
鏃犻攣鏈夊簭閾捐〃鐨勫疄鐜?/title><link>http://m.shnenglu.com/kevinlynx/archive/2015/05/05/210555.html</link><dc:creator>Kevin Lynx</dc:creator><author>Kevin Lynx</author><pubDate>Tue, 05 May 2015 11:47:00 GMT</pubDate><guid>http://m.shnenglu.com/kevinlynx/archive/2015/05/05/210555.html</guid><wfw:comment>http://m.shnenglu.com/kevinlynx/comments/210555.html</wfw:comment><comments>http://m.shnenglu.com/kevinlynx/archive/2015/05/05/210555.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://m.shnenglu.com/kevinlynx/comments/commentRss/210555.html</wfw:commentRss><trackback:ping>http://m.shnenglu.com/kevinlynx/services/trackbacks/210555.html</trackback:ping><description><![CDATA[<div id="hvzpftn" class="entry-content"> <p>鏃犻攣鏈夊簭閾捐〃鍙互淇濊瘉鍏冪礌鐨勫敮涓鎬э紝浣垮叾鍙敤浜庡搱甯岃〃鐨勬《錛岀敋鑷崇洿鎺ヤ綔涓轟竴涓晥鐜囦笉閭d箞楂樼殑map銆傛櫘閫氶摼琛ㄧ殑鏃犻攣瀹炵幇鐩稿綆鍗曠偣錛屽洜涓烘彃鍏ュ厓绱犲彲浠ュ湪琛ㄥご鎻掞紝鑰屾湁搴忛摼琛ㄧ殑鎻掑叆鍒欐槸浠繪剰浣嶇疆銆?/p> <p>鏈枃涓昏鍩轟簬璁烘枃<a >High Performance Dynamic Lock-Free Hash Tables</a>瀹炵幇銆?/p> <h2>涓昏闂</h2> <p>閾捐〃鐨勪富瑕佹搷浣滃寘鍚?code>insert</code>鍜?code>remove</code>錛屽厛綆鍗曞疄鐜頒竴涓増鏈紝灝變細(xì)鐪嬪埌闂鎵鍦紝浠ヤ笅浠g爜鍙敤浣滅ず渚嬶細(xì)</p> <div id="hvzpftn" class="highlight"><pre><code class="language-c--" data-lang="c++"><span id="hvzpftn" class="k">struct</span> <span id="hvzpftn" class="kt">node_t</span> <span id="hvzpftn" class="p">{</span> <span id="hvzpftn" class="kt">key_t</span> <span id="hvzpftn" class="n">key</span><span id="hvzpftn" class="p">;</span> <span id="hvzpftn" class="kt">value_t</span> <span id="hvzpftn" class="n">val</span><span id="hvzpftn" class="p">;</span> <span id="hvzpftn" class="kt">node_t</span> <span id="hvzpftn" class="o">*</span><span id="hvzpftn" class="n">next</span><span id="hvzpftn" class="p">;</span> <span id="hvzpftn" class="p">};</span> <span id="hvzpftn" class="kt">int</span> <span id="hvzpftn" class="nf">l_find</span><span id="hvzpftn" class="p">(</span><span id="hvzpftn" class="kt">node_t</span> <span id="hvzpftn" class="o">**</span><span id="hvzpftn" class="n">pred_ptr</span><span id="hvzpftn" class="p">,</span> <span id="hvzpftn" class="kt">node_t</span> <span id="hvzpftn" class="o">**</span><span id="hvzpftn" class="n">item_ptr</span><span id="hvzpftn" class="p">,</span> <span id="hvzpftn" class="kt">node_t</span> <span id="hvzpftn" class="o">*</span><span id="hvzpftn" class="n">head</span><span id="hvzpftn" class="p">,</span> <span id="hvzpftn" class="kt">key_t</span> <span id="hvzpftn" class="n">key</span><span id="hvzpftn" class="p">)</span> <span id="hvzpftn" class="p">{</span> <span id="hvzpftn" class="kt">node_t</span> <span id="hvzpftn" class="o">*</span><span id="hvzpftn" class="n">pred</span> <span id="hvzpftn" class="o">=</span> <span id="hvzpftn" class="n">head</span><span id="hvzpftn" class="p">;</span> <span id="hvzpftn" class="kt">node_t</span> <span id="hvzpftn" class="o">*</span><span id="hvzpftn" class="n">item</span> <span id="hvzpftn" class="o">=</span> <span id="hvzpftn" class="n">head</span><span id="hvzpftn" class="o">-></span><span id="hvzpftn" class="n">next</span><span id="hvzpftn" class="p">;</span> <span id="hvzpftn" class="k">while</span> <span id="hvzpftn" class="p">(</span><span id="hvzpftn" class="n">item</span><span id="hvzpftn" class="p">)</span> <span id="hvzpftn" class="p">{</span> <span id="hvzpftn" class="kt">int</span> <span id="hvzpftn" class="n">d</span> <span id="hvzpftn" class="o">=</span> <span id="hvzpftn" class="n">KEY_CMP</span><span id="hvzpftn" class="p">(</span><span id="hvzpftn" class="n">item</span><span id="hvzpftn" class="o">-></span><span id="hvzpftn" class="n">key</span><span id="hvzpftn" class="p">,</span> <span id="hvzpftn" class="n">key</span><span id="hvzpftn" class="p">);</span> <span id="hvzpftn" class="k">if</span> <span id="hvzpftn" class="p">(</span><span id="hvzpftn" class="n">d</span> <span id="hvzpftn" class="o">>=</span> <span id="hvzpftn" class="mi">0</span><span id="hvzpftn" class="p">)</span> <span id="hvzpftn" class="p">{</span> <span id="hvzpftn" class="o">*</span><span id="hvzpftn" class="n">pred_ptr</span> <span id="hvzpftn" class="o">=</span> <span id="hvzpftn" class="n">pred</span><span id="hvzpftn" class="p">;</span> <span id="hvzpftn" class="o">*</span><span id="hvzpftn" class="n">item_ptr</span> <span id="hvzpftn" class="o">=</span> <span id="hvzpftn" class="n">item</span><span id="hvzpftn" class="p">;</span> <span id="hvzpftn" class="k">return</span> <span id="hvzpftn" class="n">d</span> <span id="hvzpftn" class="o">==</span> <span id="hvzpftn" class="mi">0</span> <span id="hvzpftn" class="o">?</span> <span id="hvzpftn" class="nl">TRUE</span> <span id="hvzpftn" class="p">:</span> <span id="hvzpftn" class="n">FALSE</span><span id="hvzpftn" class="p">;</span> <span id="hvzpftn" class="p">}</span> <span id="hvzpftn" class="n">pred</span> <span id="hvzpftn" class="o">=</span> <span id="hvzpftn" class="n">item</span><span id="hvzpftn" class="p">;</span> <span id="hvzpftn" class="n">item</span> <span id="hvzpftn" class="o">=</span> <span id="hvzpftn" class="n">item</span><span id="hvzpftn" class="o">-></span><span id="hvzpftn" class="n">next</span><span id="hvzpftn" class="p">;</span> <span id="hvzpftn" class="p">}</span> <span id="hvzpftn" class="o">*</span><span id="hvzpftn" class="n">pred_ptr</span> <span id="hvzpftn" class="o">=</span> <span id="hvzpftn" class="n">pred</span><span id="hvzpftn" class="p">;</span> <span id="hvzpftn" class="o">*</span><span id="hvzpftn" class="n">item_ptr</span> <span id="hvzpftn" class="o">=</span> <span id="hvzpftn" class="nb">NULL</span><span id="hvzpftn" class="p">;</span> <span id="hvzpftn" class="k">return</span> <span id="hvzpftn" class="n">FALSE</span><span id="hvzpftn" class="p">;</span> <span id="hvzpftn" class="p">}</span> <span id="hvzpftn" class="kt">int</span> <span id="hvzpftn" class="nf">l_insert</span><span id="hvzpftn" class="p">(</span><span id="hvzpftn" class="kt">node_t</span> <span id="hvzpftn" class="o">*</span><span id="hvzpftn" class="n">head</span><span id="hvzpftn" class="p">,</span> <span id="hvzpftn" class="kt">key_t</span> <span id="hvzpftn" class="n">key</span><span id="hvzpftn" class="p">,</span> <span id="hvzpftn" class="kt">value_t</span> <span id="hvzpftn" class="n">val</span><span id="hvzpftn" class="p">)</span> <span id="hvzpftn" class="p">{</span> <span id="hvzpftn" class="kt">node_t</span> <span id="hvzpftn" class="o">*</span><span id="hvzpftn" class="n">pred</span><span id="hvzpftn" class="p">,</span> <span id="hvzpftn" class="o">*</span><span id="hvzpftn" class="n">item</span><span id="hvzpftn" class="p">,</span> <span id="hvzpftn" class="o">*</span><span id="hvzpftn" class="n">new_item</span><span id="hvzpftn" class="p">;</span> <span id="hvzpftn" class="k">while</span> <span id="hvzpftn" class="p">(</span><span id="hvzpftn" class="n">TRUE</span><span id="hvzpftn" class="p">)</span> <span id="hvzpftn" class="p">{</span> <span id="hvzpftn" class="k">if</span> <span id="hvzpftn" class="p">(</span><span id="hvzpftn" class="n">l_find</span><span id="hvzpftn" class="p">(</span><span id="hvzpftn" class="o">&</span><span id="hvzpftn" class="n">pred</span><span id="hvzpftn" class="p">,</span> <span id="hvzpftn" class="o">&</span><span id="hvzpftn" class="n">item</span><span id="hvzpftn" class="p">,</span> <span id="hvzpftn" class="n">head</span><span id="hvzpftn" class="p">,</span> <span id="hvzpftn" class="n">key</span><span id="hvzpftn" class="p">))</span> <span id="hvzpftn" class="p">{</span> <span id="hvzpftn" class="k">return</span> <span id="hvzpftn" class="n">FALSE</span><span id="hvzpftn" class="p">;</span> <span id="hvzpftn" class="p">}</span> <span id="hvzpftn" class="n">new_item</span> <span id="hvzpftn" class="o">=</span> <span id="hvzpftn" class="p">(</span><span id="hvzpftn" class="kt">node_t</span><span id="hvzpftn" class="o">*</span><span id="hvzpftn" class="p">)</span> <span id="hvzpftn" class="n">malloc</span><span id="hvzpftn" class="p">(</span><span id="hvzpftn" class="k">sizeof</span><span id="hvzpftn" class="p">(</span><span id="hvzpftn" class="kt">node_t</span><span id="hvzpftn" class="p">));</span> <span id="hvzpftn" class="n">new_item</span><span id="hvzpftn" class="o">-></span><span id="hvzpftn" class="n">key</span> <span id="hvzpftn" class="o">=</span> <span id="hvzpftn" class="n">key</span><span id="hvzpftn" class="p">;</span> <span id="hvzpftn" class="n">new_item</span><span id="hvzpftn" class="o">-></span><span id="hvzpftn" class="n">val</span> <span id="hvzpftn" class="o">=</span> <span id="hvzpftn" class="n">val</span><span id="hvzpftn" class="p">;</span> <span id="hvzpftn" class="n">new_item</span><span id="hvzpftn" class="o">-></span><span id="hvzpftn" class="n">next</span> <span id="hvzpftn" class="o">=</span> <span id="hvzpftn" class="n">item</span><span id="hvzpftn" class="p">;</span> <span id="hvzpftn" class="c1">// A. 濡傛灉pred鏈韓琚Щ闄や簡(jiǎn)</span> <span id="hvzpftn" class="k">if</span> <span id="hvzpftn" class="p">(</span><span id="hvzpftn" class="n">CAS</span><span id="hvzpftn" class="p">(</span><span id="hvzpftn" class="o">&</span><span id="hvzpftn" class="n">pred</span><span id="hvzpftn" class="o">-></span><span id="hvzpftn" class="n">next</span><span id="hvzpftn" class="p">,</span> <span id="hvzpftn" class="n">item</span><span id="hvzpftn" class="p">,</span> <span id="hvzpftn" class="n">new_item</span><span id="hvzpftn" class="p">))</span> <span id="hvzpftn" class="p">{</span> <span id="hvzpftn" class="k">return</span> <span id="hvzpftn" class="n">TRUE</span><span id="hvzpftn" class="p">;</span> <span id="hvzpftn" class="p">}</span> <span id="hvzpftn" class="n">free</span><span id="hvzpftn" class="p">(</span><span id="hvzpftn" class="n">new_item</span><span id="hvzpftn" class="p">);</span> <span id="hvzpftn" class="p">}</span> <span id="hvzpftn" class="p">}</span> <span id="hvzpftn" class="kt">int</span> <span id="hvzpftn" class="nf">l_remove</span><span id="hvzpftn" class="p">(</span><span id="hvzpftn" class="kt">node_t</span> <span id="hvzpftn" class="o">*</span><span id="hvzpftn" class="n">head</span><span id="hvzpftn" class="p">,</span> <span id="hvzpftn" class="kt">key_t</span> <span id="hvzpftn" class="n">key</span><span id="hvzpftn" class="p">)</span> <span id="hvzpftn" class="p">{</span> <span id="hvzpftn" class="kt">node_t</span> <span id="hvzpftn" class="o">*</span><span id="hvzpftn" class="n">pred</span><span id="hvzpftn" class="p">,</span> <span id="hvzpftn" class="o">*</span><span id="hvzpftn" class="n">item</span><span id="hvzpftn" class="p">;</span> <span id="hvzpftn" class="k">while</span> <span id="hvzpftn" class="p">(</span><span id="hvzpftn" class="n">TRUE</span><span id="hvzpftn" class="p">)</span> <span id="hvzpftn" class="p">{</span> <span id="hvzpftn" class="k">if</span> <span id="hvzpftn" class="p">(</span><span id="hvzpftn" class="o">!</span><span id="hvzpftn" class="n">l_find</span><span id="hvzpftn" class="p">(</span><span id="hvzpftn" class="o">&</span><span id="hvzpftn" class="n">pred</span><span id="hvzpftn" class="p">,</span> <span id="hvzpftn" class="o">&</span><span id="hvzpftn" class="n">item</span><span id="hvzpftn" class="p">,</span> <span id="hvzpftn" class="n">head</span><span id="hvzpftn" class="p">,</span> <span id="hvzpftn" class="n">key</span><span id="hvzpftn" class="p">))</span> <span id="hvzpftn" class="p">{</span> <span id="hvzpftn" class="k">return</span> <span id="hvzpftn" class="n">TRUE</span><span id="hvzpftn" class="p">;</span> <span id="hvzpftn" class="p">}</span> <span id="hvzpftn" class="c1">// B. 濡傛灉pred琚Щ闄わ紱濡傛灉item涔熻縐婚櫎</span> <span id="hvzpftn" class="k">if</span> <span id="hvzpftn" class="p">(</span><span id="hvzpftn" class="n">CAS</span><span id="hvzpftn" class="p">(</span><span id="hvzpftn" class="o">&</span><span id="hvzpftn" class="n">pred</span><span id="hvzpftn" class="o">-></span><span id="hvzpftn" class="n">next</span><span id="hvzpftn" class="p">,</span> <span id="hvzpftn" class="n">item</span><span id="hvzpftn" class="p">,</span> <span id="hvzpftn" class="n">item</span><span id="hvzpftn" class="o">-></span><span id="hvzpftn" class="n">next</span><span id="hvzpftn" class="p">))</span> <span id="hvzpftn" class="p">{</span> <span id="hvzpftn" class="n">haz_free</span><span id="hvzpftn" class="p">(</span><span id="hvzpftn" class="n">item</span><span id="hvzpftn" class="p">);</span> <span id="hvzpftn" class="k">return</span> <span id="hvzpftn" class="n">TRUE</span><span id="hvzpftn" class="p">;</span> <span id="hvzpftn" class="p">}</span> <span id="hvzpftn" class="p">}</span> <span id="hvzpftn" class="p">}</span></code></pre></div> <!-- more --> <p><code>l_find</code>鍑芥暟榪斿洖鏌ユ壘鍒扮殑鍓嶅簭鍏冪礌鍜屽厓绱犳湰韜紝浠g爜A鍜孊铏界劧鎷垮埌浜?code>pred</code>鍜?code>item</code>錛屼絾鍦?code>CAS</code>鐨勬椂鍊欙紝鍏跺彲鑳借鍏朵粬綰跨▼縐婚櫎銆傜敋鑷籌紝鍦?code>l_find</code>榪囩▼涓紝鍏舵瘡涓涓厓绱犻兘鍙兘琚Щ闄ゃ傞棶棰樺湪浜庯紝<strong>浠諱綍鏃跺欐嬁鍒頒竴涓厓绱犳椂錛岄兘涓嶇‘瀹氬叾鏄惁榪樻湁鏁?/strong>銆傚厓绱犵殑鏈夋晥鎬у寘鎷叾鏄惁榪樺湪閾捐〃涓紝鍏舵寚鍚戠殑鍐呭瓨鏄惁榪樻湁鏁堛?/p> <h2>瑙e喅鏂規(guī)</h2> <p><strong>閫氳繃涓哄厓绱犳寚閽堝鍔犱竴涓湁鏁堟ф爣蹇椾綅錛岄厤鍚圕AS鎿嶄綔鐨勪簰鏂ユ?/strong>錛屽氨鍙互瑙e喅鍏冪礌鏈夋晥鎬у垽瀹氶棶棰樸?/p> <p>鍥犱負(fù)<code>node_t</code>鏀懼湪鍐呭瓨?shù)腑鏄細(xì)瀵归綈鐨勫Q屾墍浠ユ寚鍚?code>node_t</code>鐨勬寚閽堝間綆鍑犱綅鏄笉浼?xì)鐢ㄥ埌鐨勫Q屼粠鑰屽彲浠ュ湪浣庡嚑浣嶉噷璁劇疆鏍囧織錛岃繖鏍峰湪鍋欳AS鐨勬椂鍊欙紝灝卞疄鐜頒簡(jiǎn)DCAS鐨勬晥鏋滐紝鐩稿綋浜庡皢涓や釜閫昏緫涓婄殑鎿嶄綔鍙樻垚浜?jiǎn)涓涓師瀛愭搷浣溿傛兂璞′笅寮曠敤璁℃暟瀵硅薄鐨勭嚎紼嬪畨鍏ㄦэ紝鍏跺唴鍖呰鐨勬寚閽堟槸綰跨▼瀹夊叏鐨勶紝浣嗗璞℃湰韜笉鏄?/p> <p>CAS鐨勪簰鏂ユэ紝鍦ㄨ嫢騫蹭釜綰跨▼CAS鐩稿悓鐨勫璞℃椂錛屽彧鏈変竴涓嚎紼嬩細(xì)鎴愬姛錛屽け璐ョ殑綰跨▼灝卞彲浠ヤ互姝ゅ垽瀹氱洰鏍囧璞″彂鐢熶簡(jiǎn)鍙樻洿銆傛敼榪涘悗鐨勪唬鐮侊紙浠g爜浠呭仛紺轟緥鐢紝涓嶄繚璇佹紜級(jí)錛?/p> <div id="hvzpftn" class="highlight"><pre><code class="language-c--" data-lang="c++"><span id="hvzpftn" class="k">typedef</span> <span id="hvzpftn" class="kt">size_t</span> <span id="hvzpftn" class="kt">markable_t</span><span id="hvzpftn" class="p">;</span> <span id="hvzpftn" class="c1">// 鏈浣庝綅緗?錛岃〃紺哄厓绱犺鍒犻櫎</span> <span id="hvzpftn" class="cp">#define HAS_MARK(p) ((markable_t)p & 0x01)</span> <span id="hvzpftn" class="cp">#define MARK(p) ((markable_t)p | 0x01)</span> <span id="hvzpftn" class="cp">#define STRIP_MARK(p) ((markable_t)p & ~0x01)</span> <span id="hvzpftn" class="kt">int</span> <span id="hvzpftn" class="nf">l_insert</span><span id="hvzpftn" class="p">(</span><span id="hvzpftn" class="kt">node_t</span> <span id="hvzpftn" class="o">*</span><span id="hvzpftn" class="n">head</span><span id="hvzpftn" class="p">,</span> <span id="hvzpftn" class="kt">key_t</span> <span id="hvzpftn" class="n">key</span><span id="hvzpftn" class="p">,</span> <span id="hvzpftn" class="kt">value_t</span> <span id="hvzpftn" class="n">val</span><span id="hvzpftn" class="p">)</span> <span id="hvzpftn" class="p">{</span> <span id="hvzpftn" class="kt">node_t</span> <span id="hvzpftn" class="o">*</span><span id="hvzpftn" class="n">pred</span><span id="hvzpftn" class="p">,</span> <span id="hvzpftn" class="o">*</span><span id="hvzpftn" class="n">item</span><span id="hvzpftn" class="p">,</span> <span id="hvzpftn" class="o">*</span><span id="hvzpftn" class="n">new_item</span><span id="hvzpftn" class="p">;</span> <span id="hvzpftn" class="k">while</span> <span id="hvzpftn" class="p">(</span><span id="hvzpftn" class="n">TRUE</span><span id="hvzpftn" class="p">)</span> <span id="hvzpftn" class="p">{</span> <span id="hvzpftn" class="k">if</span> <span id="hvzpftn" class="p">(</span><span id="hvzpftn" class="n">l_find</span><span id="hvzpftn" class="p">(</span><span id="hvzpftn" class="o">&</span><span id="hvzpftn" class="n">pred</span><span id="hvzpftn" class="p">,</span> <span id="hvzpftn" class="o">&</span><span id="hvzpftn" class="n">item</span><span id="hvzpftn" class="p">,</span> <span id="hvzpftn" class="n">head</span><span id="hvzpftn" class="p">,</span> <span id="hvzpftn" class="n">key</span><span id="hvzpftn" class="p">))</span> <span id="hvzpftn" class="p">{</span> <span id="hvzpftn" class="k">return</span> <span id="hvzpftn" class="n">FALSE</span><span id="hvzpftn" class="p">;</span> <span id="hvzpftn" class="p">}</span> <span id="hvzpftn" class="n">new_item</span> <span id="hvzpftn" class="o">=</span> <span id="hvzpftn" class="p">(</span><span id="hvzpftn" class="kt">node_t</span><span id="hvzpftn" class="o">*</span><span id="hvzpftn" class="p">)</span> <span id="hvzpftn" class="n">malloc</span><span id="hvzpftn" class="p">(</span><span id="hvzpftn" class="k">sizeof</span><span id="hvzpftn" class="p">(</span><span id="hvzpftn" class="kt">node_t</span><span id="hvzpftn" class="p">));</span> <span id="hvzpftn" class="n">new_item</span><span id="hvzpftn" class="o">-></span><span id="hvzpftn" class="n">key</span> <span id="hvzpftn" class="o">=</span> <span id="hvzpftn" class="n">key</span><span id="hvzpftn" class="p">;</span> <span id="hvzpftn" class="n">new_item</span><span id="hvzpftn" class="o">-></span><span id="hvzpftn" class="n">val</span> <span id="hvzpftn" class="o">=</span> <span id="hvzpftn" class="n">val</span><span id="hvzpftn" class="p">;</span> <span id="hvzpftn" class="n">new_item</span><span id="hvzpftn" class="o">-></span><span id="hvzpftn" class="n">next</span> <span id="hvzpftn" class="o">=</span> <span id="hvzpftn" class="n">item</span><span id="hvzpftn" class="p">;</span> <span id="hvzpftn" class="c1">// A. 铏界劧find鎷垮埌浜?jiǎn)鍚堟硶鐨刾red錛屼絾鏄湪浠ヤ笅浠g爜涔嬪墠pred鍙兘琚垹闄わ紝姝ゆ椂pred->next琚爣璁?/span> <span id="hvzpftn" class="c1">// pred->next != item錛岃CAS浼?xì)澶辫触锛屽まp觸鍚庨噸璇?/span> <span id="hvzpftn" class="k">if</span> <span id="hvzpftn" class="p">(</span><span id="hvzpftn" class="n">CAS</span><span id="hvzpftn" class="p">(</span><span id="hvzpftn" class="o">&</span><span id="hvzpftn" class="n">pred</span><span id="hvzpftn" class="o">-></span><span id="hvzpftn" class="n">next</span><span id="hvzpftn" class="p">,</span> <span id="hvzpftn" class="n">item</span><span id="hvzpftn" class="p">,</span> <span id="hvzpftn" class="n">new_item</span><span id="hvzpftn" class="p">))</span> <span id="hvzpftn" class="p">{</span> <span id="hvzpftn" class="k">return</span> <span id="hvzpftn" class="n">TRUE</span><span id="hvzpftn" class="p">;</span> <span id="hvzpftn" class="p">}</span> <span id="hvzpftn" class="n">free</span><span id="hvzpftn" class="p">(</span><span id="hvzpftn" class="n">new_item</span><span id="hvzpftn" class="p">);</span> <span id="hvzpftn" class="p">}</span> <span id="hvzpftn" class="k">return</span> <span id="hvzpftn" class="n">FALSE</span><span id="hvzpftn" class="p">;</span> <span id="hvzpftn" class="p">}</span> <span id="hvzpftn" class="kt">int</span> <span id="hvzpftn" class="nf">l_remove</span><span id="hvzpftn" class="p">(</span><span id="hvzpftn" class="kt">node_t</span> <span id="hvzpftn" class="o">*</span><span id="hvzpftn" class="n">head</span><span id="hvzpftn" class="p">,</span> <span id="hvzpftn" class="kt">key_t</span> <span id="hvzpftn" class="n">key</span><span id="hvzpftn" class="p">)</span> <span id="hvzpftn" class="p">{</span> <span id="hvzpftn" class="kt">node_t</span> <span id="hvzpftn" class="o">*</span><span id="hvzpftn" class="n">pred</span><span id="hvzpftn" class="p">,</span> <span id="hvzpftn" class="o">*</span><span id="hvzpftn" class="n">item</span><span id="hvzpftn" class="p">;</span> <span id="hvzpftn" class="k">while</span> <span id="hvzpftn" class="p">(</span><span id="hvzpftn" class="n">TRUE</span><span id="hvzpftn" class="p">)</span> <span id="hvzpftn" class="p">{</span> <span id="hvzpftn" class="k">if</span> <span id="hvzpftn" class="p">(</span><span id="hvzpftn" class="o">!</span><span id="hvzpftn" class="n">l_find</span><span id="hvzpftn" class="p">(</span><span id="hvzpftn" class="o">&</span><span id="hvzpftn" class="n">pred</span><span id="hvzpftn" class="p">,</span> <span id="hvzpftn" class="o">&</span><span id="hvzpftn" class="n">item</span><span id="hvzpftn" class="p">,</span> <span id="hvzpftn" class="n">head</span><span id="hvzpftn" class="p">,</span> <span id="hvzpftn" class="n">key</span><span id="hvzpftn" class="p">))</span> <span id="hvzpftn" class="p">{</span> <span id="hvzpftn" class="k">return</span> <span id="hvzpftn" class="n">FALSE</span><span id="hvzpftn" class="p">;</span> <span id="hvzpftn" class="p">}</span> <span id="hvzpftn" class="kt">node_t</span> <span id="hvzpftn" class="o">*</span><span id="hvzpftn" class="n">inext</span> <span id="hvzpftn" class="o">=</span> <span id="hvzpftn" class="n">item</span><span id="hvzpftn" class="o">-></span><span id="hvzpftn" class="n">next</span><span id="hvzpftn" class="p">;</span> <span id="hvzpftn" class="c1">// B. 鍒犻櫎item鍓嶅厛鏍囪item->next錛屽鏋淐AS澶辮觸錛岄偅涔堟儏鍐靛悓insert涓鏍鳳紝鏈夊叾浠栫嚎紼嬪湪find涔嬪悗</span> <span id="hvzpftn" class="c1">// 鍒犻櫎浜?jiǎn)item錛屽け璐ュ悗閲嶈瘯</span> <span id="hvzpftn" class="k">if</span> <span id="hvzpftn" class="p">(</span><span id="hvzpftn" class="o">!</span><span id="hvzpftn" class="n">CAS</span><span id="hvzpftn" class="p">(</span><span id="hvzpftn" class="o">&</span><span id="hvzpftn" class="n">item</span><span id="hvzpftn" class="o">-></span><span id="hvzpftn" class="n">next</span><span id="hvzpftn" class="p">,</span> <span id="hvzpftn" class="n">inext</span><span id="hvzpftn" class="p">,</span> <span id="hvzpftn" class="n">MARK</span><span id="hvzpftn" class="p">(</span><span id="hvzpftn" class="n">inext</span><span id="hvzpftn" class="p">)))</span> <span id="hvzpftn" class="p">{</span> <span id="hvzpftn" class="k">continue</span><span id="hvzpftn" class="p">;</span> <span id="hvzpftn" class="p">}</span> <span id="hvzpftn" class="c1">// C. 瀵瑰悓涓涓厓绱爄tem鍒犻櫎鏃訛紝鍙細(xì)鏈変竴涓嚎紼嬫垚鍔熻蛋鍒拌繖閲?/span> <span id="hvzpftn" class="k">if</span> <span id="hvzpftn" class="p">(</span><span id="hvzpftn" class="n">CAS</span><span id="hvzpftn" class="p">(</span><span id="hvzpftn" class="o">&</span><span id="hvzpftn" class="n">pred</span><span id="hvzpftn" class="o">-></span><span id="hvzpftn" class="n">next</span><span id="hvzpftn" class="p">,</span> <span id="hvzpftn" class="n">item</span><span id="hvzpftn" class="p">,</span> <span id="hvzpftn" class="n">STRIP_MARK</span><span id="hvzpftn" class="p">(</span><span id="hvzpftn" class="n">item</span><span id="hvzpftn" class="o">-></span><span id="hvzpftn" class="n">next</span><span id="hvzpftn" class="p">)))</span> <span id="hvzpftn" class="p">{</span> <span id="hvzpftn" class="n">haz_defer_free</span><span id="hvzpftn" class="p">(</span><span id="hvzpftn" class="n">item</span><span id="hvzpftn" class="p">);</span> <span id="hvzpftn" class="k">return</span> <span id="hvzpftn" class="n">TRUE</span><span id="hvzpftn" class="p">;</span> <span id="hvzpftn" class="p">}</span> <span id="hvzpftn" class="p">}</span> <span id="hvzpftn" class="k">return</span> <span id="hvzpftn" class="n">FALSE</span><span id="hvzpftn" class="p">;</span> <span id="hvzpftn" class="p">}</span> <span id="hvzpftn" class="kt">int</span> <span id="hvzpftn" class="nf">l_find</span><span id="hvzpftn" class="p">(</span><span id="hvzpftn" class="kt">node_t</span> <span id="hvzpftn" class="o">**</span><span id="hvzpftn" class="n">pred_ptr</span><span id="hvzpftn" class="p">,</span> <span id="hvzpftn" class="kt">node_t</span> <span id="hvzpftn" class="o">**</span><span id="hvzpftn" class="n">item_ptr</span><span id="hvzpftn" class="p">,</span> <span id="hvzpftn" class="kt">node_t</span> <span id="hvzpftn" class="o">*</span><span id="hvzpftn" class="n">head</span><span id="hvzpftn" class="p">,</span> <span id="hvzpftn" class="kt">key_t</span> <span id="hvzpftn" class="n">key</span><span id="hvzpftn" class="p">)</span> <span id="hvzpftn" class="p">{</span> <span id="hvzpftn" class="kt">node_t</span> <span id="hvzpftn" class="o">*</span><span id="hvzpftn" class="n">pred</span> <span id="hvzpftn" class="o">=</span> <span id="hvzpftn" class="n">head</span><span id="hvzpftn" class="p">;</span> <span id="hvzpftn" class="kt">node_t</span> <span id="hvzpftn" class="o">*</span><span id="hvzpftn" class="n">item</span> <span id="hvzpftn" class="o">=</span> <span id="hvzpftn" class="n">head</span><span id="hvzpftn" class="o">-></span><span id="hvzpftn" class="n">next</span><span id="hvzpftn" class="p">;</span> <span id="hvzpftn" class="kt">hazard_t</span> <span id="hvzpftn" class="o">*</span><span id="hvzpftn" class="n">hp1</span> <span id="hvzpftn" class="o">=</span> <span id="hvzpftn" class="n">haz_get</span><span id="hvzpftn" class="p">(</span><span id="hvzpftn" class="mi">0</span><span id="hvzpftn" class="p">);</span> <span id="hvzpftn" class="kt">hazard_t</span> <span id="hvzpftn" class="o">*</span><span id="hvzpftn" class="n">hp2</span> <span id="hvzpftn" class="o">=</span> <span id="hvzpftn" class="n">haz_get</span><span id="hvzpftn" class="p">(</span><span id="hvzpftn" class="mi">1</span><span id="hvzpftn" class="p">);</span> <span id="hvzpftn" class="k">while</span> <span id="hvzpftn" class="p">(</span><span id="hvzpftn" class="n">item</span><span id="hvzpftn" class="p">)</span> <span id="hvzpftn" class="p">{</span> <span id="hvzpftn" class="n">haz_set_ptr</span><span id="hvzpftn" class="p">(</span><span id="hvzpftn" class="n">hp1</span><span id="hvzpftn" class="p">,</span> <span id="hvzpftn" class="n">pred</span><span id="hvzpftn" class="p">);</span> <span id="hvzpftn" class="n">haz_set_ptr</span><span id="hvzpftn" class="p">(</span><span id="hvzpftn" class="n">hp2</span><span id="hvzpftn" class="p">,</span> <span id="hvzpftn" class="n">item</span><span id="hvzpftn" class="p">);</span> <span id="hvzpftn" class="cm">/* </span> <span id="hvzpftn" class="cm"> 濡傛灉宸茶鏍囪錛岄偅涔堢揣鎺ョ潃item鍙兘琚Щ闄ら摼琛ㄧ敋鑷抽噴鏀撅紝鎵浠ラ渶瑕侀噸澶存煡鎵?/span> <span id="hvzpftn" class="cm"> */</span> <span id="hvzpftn" class="k">if</span> <span id="hvzpftn" class="p">(</span><span id="hvzpftn" class="n">HAS_MARK</span><span id="hvzpftn" class="p">(</span><span id="hvzpftn" class="n">item</span><span id="hvzpftn" class="o">-></span><span id="hvzpftn" class="n">next</span><span id="hvzpftn" class="p">))</span> <span id="hvzpftn" class="p">{</span> <span id="hvzpftn" class="k">return</span> <span id="hvzpftn" class="n">l_find</span><span id="hvzpftn" class="p">(</span><span id="hvzpftn" class="n">pred_ptr</span><span id="hvzpftn" class="p">,</span> <span id="hvzpftn" class="n">item_ptr</span><span id="hvzpftn" class="p">,</span> <span id="hvzpftn" class="n">head</span><span id="hvzpftn" class="p">,</span> <span id="hvzpftn" class="n">key</span><span id="hvzpftn" class="p">);</span> <span id="hvzpftn" class="p">}</span> <span id="hvzpftn" class="kt">int</span> <span id="hvzpftn" class="n">d</span> <span id="hvzpftn" class="o">=</span> <span id="hvzpftn" class="n">KEY_CMP</span><span id="hvzpftn" class="p">(</span><span id="hvzpftn" class="n">item</span><span id="hvzpftn" class="o">-></span><span id="hvzpftn" class="n">key</span><span id="hvzpftn" class="p">,</span> <span id="hvzpftn" class="n">key</span><span id="hvzpftn" class="p">);</span> <span id="hvzpftn" class="k">if</span> <span id="hvzpftn" class="p">(</span><span id="hvzpftn" class="n">d</span> <span id="hvzpftn" class="o">>=</span> <span id="hvzpftn" class="mi">0</span><span id="hvzpftn" class="p">)</span> <span id="hvzpftn" class="p">{</span> <span id="hvzpftn" class="o">*</span><span id="hvzpftn" class="n">pred_ptr</span> <span id="hvzpftn" class="o">=</span> <span id="hvzpftn" class="n">pred</span><span id="hvzpftn" class="p">;</span> <span id="hvzpftn" class="o">*</span><span id="hvzpftn" class="n">item_ptr</span> <span id="hvzpftn" class="o">=</span> <span id="hvzpftn" class="n">item</span><span id="hvzpftn" class="p">;</span> <span id="hvzpftn" class="k">return</span> <span id="hvzpftn" class="n">d</span> <span id="hvzpftn" class="o">==</span> <span id="hvzpftn" class="mi">0</span> <span id="hvzpftn" class="o">?</span> <span id="hvzpftn" class="nl">TRUE</span> <span id="hvzpftn" class="p">:</span> <span id="hvzpftn" class="n">FALSE</span><span id="hvzpftn" class="p">;</span> <span id="hvzpftn" class="p">}</span> <span id="hvzpftn" class="n">pred</span> <span id="hvzpftn" class="o">=</span> <span id="hvzpftn" class="n">item</span><span id="hvzpftn" class="p">;</span> <span id="hvzpftn" class="n">item</span> <span id="hvzpftn" class="o">=</span> <span id="hvzpftn" class="n">item</span><span id="hvzpftn" class="o">-></span><span id="hvzpftn" class="n">next</span><span id="hvzpftn" class="p">;</span> <span id="hvzpftn" class="p">}</span> <span id="hvzpftn" class="o">*</span><span id="hvzpftn" class="n">pred_ptr</span> <span id="hvzpftn" class="o">=</span> <span id="hvzpftn" class="n">pred</span><span id="hvzpftn" class="p">;</span> <span id="hvzpftn" class="o">*</span><span id="hvzpftn" class="n">item_ptr</span> <span id="hvzpftn" class="o">=</span> <span id="hvzpftn" class="nb">NULL</span><span id="hvzpftn" class="p">;</span> <span id="hvzpftn" class="k">return</span> <span id="hvzpftn" class="n">FALSE</span><span id="hvzpftn" class="p">;</span> <span id="hvzpftn" class="p">}</span></code></pre></div> <p><code>haz_get</code>銆?code>haz_set_ptr</code>涔嬬被鐨勫嚱鏁版槸涓涓猦azard pointer瀹炵幇錛岀敤浜庢敮鎸佸綰跨▼涓嬪唴瀛樼殑GC銆備笂闈㈢殑浠g爜涓紝瑕佸垹闄や竴涓厓绱?code>item</code>鏃訛紝浼?xì)鏍囪?code>item->next</code>錛屼粠鑰屼嬌寰?code>insert</code>鏃朵腑閭d釜<code>CAS</code>涓嶉渶瑕佸仛浠諱綍璋冩暣銆傛葷粨涓嬭繖閲岀殑綰跨▼绔炰簤鎯呭喌錛?/p> <ul> <li> <code>insert</code>涓?code>find</code>鍒版甯哥殑<code>pred</code>鍙?code>item</code>錛?code>pred->next == item</code>錛岀劧鍚庡湪<code>CAS</code>鍓嶆湁綰跨▼鍒犻櫎浜?code>pred</code>錛屾鏃?code>pred->next == MARK(item)</code>錛?code>CAS</code>澶辮觸錛岄噸璇曪紱鍒犻櫎鍒嗕負(fù)2縐嶆儏鍐碉細(xì)a) 浠庨摼琛ㄧЩ闄わ紝寰楀埌鏍囪錛?code>pred</code>鍙戶緇闂紱b) <code>pred</code>鍙兘琚噴鏀懼唴瀛橈紝姝ゆ椂鍐嶄嬌鐢?code>pred</code>浼?xì)閿欒銆備負(fù)浜?jiǎn)澶勭悊鎯呭喌b錛屾墍浠ュ紩鍏ヤ簡(jiǎn)綾諱技hazard pointer鐨勬満鍒訛紝鍙互鏈夋晥淇濋殰浠繪剰涓涓寚閽?code>p</code>鍙榪樻湁綰跨▼鍦ㄤ嬌鐢ㄥ畠錛屽畠鐨勫唴瀛樺氨涓嶄細(xì)琚湡姝i噴鏀?/li> <li> <code>insert</code>涓湁澶氫釜綰跨▼鍦?code>pred</code>鍚庢彃鍏ュ厓绱狅紝姝ゆ椂鍚屾牱鐢?code>insert</code>涓殑<code>CAS</code>淇濊瘉錛岃繖涓笉澶氳</li> <li> <code>remove</code>涓儏鍐靛悓<code>insert</code>錛?code>find</code>鎷垮埌浜?jiǎn)鏈夋晥鐨?code>pred</code>鍜?code>next</code>錛屼絾鍦?code>CAS</code>鐨勬椂鍊?code>pred</code>琚叾浠栫嚎紼嬪垹闄わ紝姝ゆ椂鎯呭喌鍚?code>insert</code>錛?code>CAS</code>澶辮觸錛岄噸璇?/li> <li>浠諱綍鏃跺欐敼鍙橀摼琛ㄧ粨鏋勬椂錛屾棤璁烘槸<code>remove</code>榪樻槸<code>insert</code>錛岄兘闇瑕侀噸璇曡鎿嶄綔</li> <li> <code>find</code>涓亶鍘嗘椂錛屽彲鑳戒細(xì)閬囧埌琚爣璁板垹闄ょ殑<code>item</code>錛屾鏃?code>item</code>鏍規(guī)嵁<code>remove</code>鐨勫疄鐜板緢鍙兘琚垹闄わ紝鎵浠ラ渶瑕侀噸澶村紑濮嬮亶鍘?/li> </ul> <h2>ABA闂</h2> <p>ABA闂榪樻槸瀛樺湪鐨勶紝<code>insert</code>涓細(xì)</p> <div id="hvzpftn" class="highlight"><pre><code class="language-c--" data-lang="c++"><span id="hvzpftn" class="k">if</span> <span id="hvzpftn" class="p">(</span><span id="hvzpftn" class="n">CAS</span><span id="hvzpftn" class="p">(</span><span id="hvzpftn" class="o">&</span><span id="hvzpftn" class="n">pred</span><span id="hvzpftn" class="o">-></span><span id="hvzpftn" class="n">next</span><span id="hvzpftn" class="p">,</span> <span id="hvzpftn" class="n">item</span><span id="hvzpftn" class="p">,</span> <span id="hvzpftn" class="n">new_item</span><span id="hvzpftn" class="p">))</span> <span id="hvzpftn" class="p">{</span> <span id="hvzpftn" class="k">return</span> <span id="hvzpftn" class="n">TRUE</span><span id="hvzpftn" class="p">;</span> <span id="hvzpftn" class="p">}</span></code></pre></div> <p>濡傛灉<code>CAS</code>涔嬪墠錛?code>pred</code>鍚庣殑<code>item</code>琚Щ闄わ紝鍙堜互鐩稿悓鐨勫湴鍧鍊煎姞榪涙潵錛屼絾鍏秜alue鍙樹(shù)簡(jiǎn)錛屾鏃?code>CAS</code>浼?xì)鎴愬姛锛屼絾閾捐〃鍙兘灏变笉鏄湁搴忕殑浜?jiǎn)銆?code>pred->val < new_item->val > item->val</code></p> <p>涓轟簡(jiǎn)瑙e喅榪欎釜闂錛屽彲浠ュ埄鐢ㄦ寚閽堝煎湴鍧瀵歸綈鐨勫叾浠栦綅鏉ュ瓨鍌ㄤ竴涓鏁幫紝鐢ㄤ簬琛ㄧず<code>pred->next</code>鐨勬敼鍙樻鏁般傚綋<code>insert</code>鎷垮埌<code>pred</code>鏃訛紝<code>pred->next</code>涓瓨鍌ㄧ殑璁℃暟鍋囪鏄?錛?code>CAS</code>涔嬪墠鍏朵粬綰跨▼縐婚櫎浜?code>pred->next</code>鍙堟柊澧炲洖浜?code>item</code>錛屾鏃?code>pred->next</code>涓殑璁℃暟澧炲姞錛屼粠鑰屽鑷?code>insert</code>涓?code>CAS</code>澶辮觸銆?/p> <div id="hvzpftn" class="highlight"><pre><code class="language-c--" data-lang="c++"><span id="hvzpftn" class="c1">// 鏈浣庝綅鐣欎綔鍒犻櫎鏍囧織</span> <span id="hvzpftn" class="cp">#define MASK ((sizeof(node_t) - 1) & ~0x01)</span> <span id="hvzpftn" class="cp">#define GET_TAG(p) ((markable_t)p & MASK)</span> <span id="hvzpftn" class="cp">#define TAG(p, tag) ((markable_t)p | (tag))</span> <span id="hvzpftn" class="cp">#define MARK(p) ((markable_t)p | 0x01)</span> <span id="hvzpftn" class="cp">#define HAS_MARK(p) ((markable_t)p & 0x01)</span> <span id="hvzpftn" class="cp">#define STRIP_MARK(p) ((node_t*)((markable_t)p & ~(MASK | 0x01)))</span></code></pre></div> <p><code>remove</code>鐨勫疄鐜幫細(xì)</p> <div id="hvzpftn" class="highlight"><pre><code class="language-c--" data-lang="c++"><span id="hvzpftn" class="cm">/* 鍏堟爣璁板啀鍒犻櫎 */</span> <span id="hvzpftn" class="k">if</span> <span id="hvzpftn" class="p">(</span><span id="hvzpftn" class="o">!</span><span id="hvzpftn" class="n">CAS</span><span id="hvzpftn" class="p">(</span><span id="hvzpftn" class="o">&</span><span id="hvzpftn" class="n">sitem</span><span id="hvzpftn" class="o">-></span><span id="hvzpftn" class="n">next</span><span id="hvzpftn" class="p">,</span> <span id="hvzpftn" class="n">inext</span><span id="hvzpftn" class="p">,</span> <span id="hvzpftn" class="n">MARK</span><span id="hvzpftn" class="p">(</span><span id="hvzpftn" class="n">inext</span><span id="hvzpftn" class="p">)))</span> <span id="hvzpftn" class="p">{</span> <span id="hvzpftn" class="k">continue</span><span id="hvzpftn" class="p">;</span> <span id="hvzpftn" class="p">}</span> <span id="hvzpftn" class="kt">int</span> <span id="hvzpftn" class="n">tag</span> <span id="hvzpftn" class="o">=</span> <span id="hvzpftn" class="n">GET_TAG</span><span id="hvzpftn" class="p">(</span><span id="hvzpftn" class="n">pred</span><span id="hvzpftn" class="o">-></span><span id="hvzpftn" class="n">next</span><span id="hvzpftn" class="p">)</span> <span id="hvzpftn" class="o">+</span> <span id="hvzpftn" class="mi">1</span><span id="hvzpftn" class="p">;</span> <span id="hvzpftn" class="k">if</span> <span id="hvzpftn" class="p">(</span><span id="hvzpftn" class="n">CAS</span><span id="hvzpftn" class="p">(</span><span id="hvzpftn" class="o">&</span><span id="hvzpftn" class="n">pred</span><span id="hvzpftn" class="o">-></span><span id="hvzpftn" class="n">next</span><span id="hvzpftn" class="p">,</span> <span id="hvzpftn" class="n">item</span><span id="hvzpftn" class="p">,</span> <span id="hvzpftn" class="n">TAG</span><span id="hvzpftn" class="p">(</span><span id="hvzpftn" class="n">STRIP_MARK</span><span id="hvzpftn" class="p">(</span><span id="hvzpftn" class="n">sitem</span><span id="hvzpftn" class="o">-></span><span id="hvzpftn" class="n">next</span><span id="hvzpftn" class="p">),</span> <span id="hvzpftn" class="n">tag</span><span id="hvzpftn" class="p">)))</span> <span id="hvzpftn" class="p">{</span> <span id="hvzpftn" class="n">haz_defer_free</span><span id="hvzpftn" class="p">(</span><span id="hvzpftn" class="n">sitem</span><span id="hvzpftn" class="p">);</span> <span id="hvzpftn" class="k">return</span> <span id="hvzpftn" class="n">TRUE</span><span id="hvzpftn" class="p">;</span> <span id="hvzpftn" class="p">}</span></code></pre></div> <p><code>insert</code>涓篃鍙互鏇存柊<code>pred->next</code>鐨勮鏁般?/p> <h2>鎬葷粨</h2> <p>鏃犻攣鐨勫疄鐜幫紝鏈川涓婇兘浼?xì)渚濊禆浜?code>CAS</code>鐨勪簰鏂ユс備粠澶村疄鐜頒竴涓猯ock free鐨勬暟鎹粨鏋勶紝鍙互娣卞埢鎰熷彈鍒發(fā)ock free瀹炵幇鐨則ricky銆傛渶緇堜唬鐮佸彲浠ヤ粠<a >榪欓噷github</a>鑾峰彇銆備唬鐮佷腑涓轟簡(jiǎn)綆鍗曪紝瀹炵幇浜?jiǎn)涓涓笉鏄緢寮哄ぇ鐨刪azard pointer錛屽彲浠?a >鍙傝冧箣鍓嶇殑鍗氭枃</a>銆?/p> <p class="post-footer"> 鍘熸枃鍦板潃錛? <a >http://codemacro.com/2015/05/05/lock_free_list/</a><br /> written by <a >Kevin Lynx</a>  posted at <a >http://codemacro.com</a> </p> </div><img src ="http://m.shnenglu.com/kevinlynx/aggbug/210555.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://m.shnenglu.com/kevinlynx/" target="_blank">Kevin Lynx</a> 2015-05-05 19:47 <a href="http://m.shnenglu.com/kevinlynx/archive/2015/05/05/210555.html#Feedback" target="_blank" style="text-decoration:none;">鍙戣〃璇勮</a></div>]]></description></item><item><title>騫惰緙栫▼涓殑鍐呭瓨鍥炴敹Hazard Pointerhttp://m.shnenglu.com/kevinlynx/archive/2015/05/03/210532.htmlKevin LynxKevin LynxSun, 03 May 2015 12:46:00 GMThttp://m.shnenglu.com/kevinlynx/archive/2015/05/03/210532.htmlhttp://m.shnenglu.com/kevinlynx/comments/210532.htmlhttp://m.shnenglu.com/kevinlynx/archive/2015/05/03/210532.html#Feedback0http://m.shnenglu.com/kevinlynx/comments/commentRss/210532.htmlhttp://m.shnenglu.com/kevinlynx/services/trackbacks/210532.html

鎺ヤ笂綃?a >浣跨敤RCU鎶鏈疄鐜拌鍐欑嚎紼嬫棤閿?/a>錛屽湪娌℃湁GC鏈哄埗鐨勮璦涓紝瑕佸疄鐜癓ock free鐨勭畻娉曪紝灝卞厤涓嶄簡(jiǎn)瑕佽嚜宸卞鐞嗗唴瀛樺洖鏀剁殑闂銆?/p>

Hazard Pointer鏄彟涓縐嶅鐞嗚繖涓棶棰樼殑綆楁硶錛岃屼笖鐩告瘮璧鋒潵涓嶄絾綆鍗曪紝鍔熻兘涔熷緢寮哄ぇ銆?a >閿佹棤鍏崇殑鏁版嵁緇撴瀯涓嶩azard鎸囬拡涓寰楀緢濂斤紝Wikipedia Hazard pointer涔熸弿榪板緱姣旇緝娓呮錛屾墍浠ユ垜榪欓噷灝變笉璁查偅涔堢粏浜?jiǎn)銆?/p>

涓涓畝鍗曠殑瀹炵幇鍙互鍙傝?a >鎴戠殑github haz_ptr.c

鍘熺悊

鍩烘湰鍘熺悊鏃犻潪涔熸槸璇葷嚎紼嬪鎸囬拡榪涜鏍囪瘑錛屾寚閽?鎸囧悜鐨勫唴瀛?瑕侀噴鏀炬椂閮戒細(xì)緙撳瓨璧鋒潵寤惰繜鍒扮‘璁ゆ病鏈夎綰跨▼浜?jiǎn)鎵嶅鍏剁湡姝i噴鏀俱?/p>

<Lock-Free Data Structures with Hazard Pointers>涓殑鎻忚堪錛?/p>

Each reader thread owns a single-writer/multi-reader shared pointer called “hazard pointer.” When a reader thread assigns the address of a map to its hazard pointer, it is basically announcing to other threads (writers), “I am reading this map. You can replace it if you want, but don’t change its contents and certainly keep your deleteing hands off it.”

鍏抽敭鐨勭粨鏋勫寘鎷細(xì)Hazard pointer銆?code>Thread Free list

Hazard pointer錛氫竴涓綰跨▼瑕佷嬌鐢ㄤ竴涓寚閽堟椂錛屽氨浼?xì)鍒涘晦Z竴涓狧azard pointer鍖呰榪欎釜鎸囬拡銆備竴涓狧azard pointer浼?xì)琚竴涓嚎紼嬪啓錛屽涓嚎紼嬭銆?/p>

struct HazardPointer {
        void *real_ptr; // 鍖呰鐨勬寚閽?/span>
        ... // 涓嶅悓鐨勫疄鐜版湁涓嶅悓鐨勬垚鍛?/span>
    };

    void func() {
        HazardPointer *hp = accquire(_real_ptr);
        ... // use _real_ptr
        release(hp);
    }

Thread Free List錛氭瘡涓嚎紼嬮兘鏈変竴涓繖鏍風(fēng)殑鍒楄〃錛屼繚瀛樼潃灝嗚閲婃斁鐨勬寚閽堝垪琛紝榪欎釜鍒楄〃浠呭搴旂殑綰跨▼璇誨啓

void defer_free(void *ptr) {
        _free_list.push_back(ptr);
    }

褰撴煇涓嚎紼嬭灝濊瘯閲婃斁Free List涓殑鎸囬拡鏃訛紝渚嬪鎸囬拡ptr錛屽氨媯(gè)鏌ユ墍鏈夊叾浠栫嚎紼嬩嬌鐢ㄧ殑Hazard pointer錛屾鏌ユ槸鍚﹀瓨鍦ㄥ寘瑁呬簡(jiǎn)ptr鐨凥azard pointer錛屽鏋滄病鏈夊垯璇存槑娌℃湁璇葷嚎紼嬫鍦ㄤ嬌鐢?code>ptr錛屽彲浠ュ畨鍏ㄩ噴鏀?code>ptr銆?/p>

void gc() {
        for(ptr in _free_list) {
            conflict = false
            for (hp in _all_hazard_pointers) {
                if (hp->_real_ptr == ptr) {
                    confilict = true
                    break
                }
            }
            if (!conflict)
                delete ptr
        }
    }

浠ヤ笂錛屽叾瀹炲氨鏄?code>Hazard Pointer鐨勪富瑕佸唴瀹廣?/p>

Hazard Pointer鐨勭鐞?/h2>

涓婇潰鐨勪唬鐮佷腑娌℃湁鎻愬埌_all_hazard_pointers鍙?code>accquire鐨勫叿浣撳疄鐜幫紝榪欏氨鏄疕azard Pointer鐨勭鐞嗛棶棰樸?/p>

銆婇攣鏃犲叧鐨勬暟鎹粨鏋勪笌Hazard鎸囬拡銆嬫枃涓垱寤轟簡(jiǎn)涓涓狶ock free鐨勯摼琛ㄦ潵琛ㄧず榪欎釜鍏ㄥ眬鐨凥azard Pointer List銆傛瘡涓狧azard Pointer鏈変竴涓垚鍛樻爣璇嗗叾鏄惁鍙敤銆傝繖涓狶ist涓篃灝變繚瀛樹(shù)簡(jiǎn)宸茬粡琚嬌鐢ㄧ殑Hazard Pointer闆嗗悎鍜屾湭琚嬌鐢ㄧ殑Hazard Pointer闆嗗悎錛屽綋鎵鏈塇azard Pointer閮借浣跨敤鏃訛紝灝變細(xì)鏂板垎閰嶄竴涓姞榪涜繖涓狶ist銆傚綋璇葷嚎紼嬩笉浣跨敤鎸囬拡鏃訛紝闇瑕佸綊榪楬azard Pointer錛岀洿鎺ヨ緗彲鐢ㄦ垚鍛樻爣璇嗗嵆鍙傝gc()鏃訛紝灝辯洿鎺ラ亶鍘嗚繖涓狶ist銆?/p>

瑕佸疄鐜頒竴涓狶ock free鐨勯摼琛紝騫朵笖浠呴渶瑕佸疄鐜板ご鎻掑叆錛岃繕鏄潪甯哥畝鍗曠殑銆傛湰韜獺azard Pointer鏍囪瘑鏌愪釜鎸囬拡鏃訛紝閮芥槸鐢ㄤ簡(jiǎn)鍚庣珛鍗蟲(chóng)爣璇嗭紝鎵浠ヨ繖涓疄鐜扮洿鎺ユ敮鎸佷簡(jiǎn)鍔ㄦ佺嚎紼嬶紝鏀寔綰跨▼鐨勬寕璧風(fēng)瓑銆?/p>

鍦?a >nbds欏圭洰涓篃鏈変竴涓狧azard Pointer鐨勫疄鐜幫紝鐩稿瑕佸急涓鐐廣傚畠涓烘瘡涓嚎紼嬮兘璁劇疆浜?jiǎn)鑷忿q殑Hazard Pointer姹狅紝鍐欑嚎紼嬭閲婃斁鎸囬拡鏃訛紝灝辮闂墍鏈夊叾浠栫嚎紼嬬殑Hazard Pointer姹犮?/p>

typedef struct haz_local {
        // Free List
        pending_t *pending; // to be freed
        int pending_size;
        int pending_count;

        // Hazard Pointer 姹狅紝鍔ㄦ佸拰闈?rùn)鎬佷袱縐?/span>
        haz_t static_haz[STATIC_HAZ_PER_THREAD];

        haz_t **dynamic;
        int dynamic_size;
        int dynamic_count;

    } __attribute__ ((aligned(CACHE_LINE_SIZE))) haz_local_t;

    static haz_local_t haz_local_[MAX_NUM_THREADS] = {};

姣忎釜綰跨▼褰撶劧灝辨秹鍙?qiáng)鍒?code>haz_local_绱㈠紩(ID)鐨勫垎閰嶏紝灝卞儚浣跨敤RCU鎶鏈疄鐜拌鍐欑嚎紼嬫棤閿?/a>涓殑涓鏍楓傝繖涓疄鐜頒負(fù)浜?jiǎn)鏀寔绾拷E嬪姩鎬佸垱寤猴紝灝遍渶瑕佷竴濂楃嚎紼婭D鐨勯噸鐢ㄦ満鍒訛紝鐩稿澶嶆潅澶氫簡(jiǎn)銆?/p>

闄勫綍

鏈鍚庯紝闄勪笂涓浜涘茍琛岀紪紼嬩腑鐨勪竴浜涙蹇點(diǎn)?/p>

Lock Free & Wait Free

甯稿父鐪嬪埌Lock Free鍜?code>Wait Free鐨勬蹇碉紝榪欎簺姒傚康鐢ㄤ簬琛¢噺涓涓郴緇熸垨鑰呰涓孌典唬鐮佺殑騫惰綰у埆錛屽茍琛岀駭鍒彲鍙傝?a >騫惰緙栫▼——騫跺彂綰у埆銆傛諱箣Wait Free鏄竴涓瘮Lock Free鏇寸墰閫肩殑綰у埆銆?/p>

鎴戣嚜宸辯殑鐞嗚В錛屼緥濡傘婇攣鏃犲叧鐨勬暟鎹粨鏋勪笌Hazard鎸囬拡銆嬩腑瀹炵幇鐨凥azard Pointer閾捐〃灝卞彲浠ヨ鏄疞ock Free鐨勶紝娉ㄦ剰瀹冨湪鎻掑叆鏂板厓绱犲埌閾捐〃澶存椂錛屽洜涓轟嬌鐢?code>CAS錛屾誨厤涓嶄簡(jiǎn)涓涓猙usy loop錛屾湁榪欎釜鐗瑰緛鐨勬儏鍐典笅灝辯畻鏄?code>Lock Free錛岃櫧鐒舵病閿侊紝浣嗘煇涓嚎紼嬬殑鎵ц鎯呭喌涔熷彈鍏朵粬綰跨▼鐨勫獎(jiǎng)鍝嶃?/p>

鐩稿鑰岃█錛?code>Wait Free鍒欐槸姣忎釜綰跨▼鐨勬墽琛岄兘鏄嫭绔嬬殑錛屼緥濡傘婇攣鏃犲叧鐨勬暟鎹粨鏋勪笌Hazard鎸囬拡銆嬩腑鐨?code>Scan鍑芥暟銆?code>“姣忎釜綰跨▼鐨勬墽琛屾椂闂撮兘涓嶄緷璧栦簬鍏跺畠浠諱綍綰跨▼鐨勮涓?#8221;

閿佹棤鍏?Lock-Free)鎰忓懗鐫緋葷粺涓誨瓨鍦ㄦ煇涓嚎紼嬭兘澶熷緱浠ョ戶緇墽琛岋紱鑰岀瓑寰呮棤鍏?Wait-Free)鍒欐槸涓涓洿寮虹殑鏉′歡錛屽畠鎰忓懗鐫鎵鏈夌嚎紼嬮兘鑳藉線涓嬭繘琛屻?/p>

ABA闂

鍦ㄥ疄鐜?code>Lock Free綆楁硶鐨勮繃紼嬩腑錛屾繪槸瑕佷嬌鐢?code>CAS鍘熻鐨勶紝鑰?code>CAS灝變細(xì)甯︽潵ABA闂銆?/p>

鍦ㄨ繘琛孋AS鎿嶄綔鐨勬椂鍊欙紝鍥犱負(fù)鍦ㄦ洿鏀筕涔嬪墠錛孋AS涓昏璇㈤棶“V鐨勫兼槸鍚︿粛鐒朵負(fù)A”錛屾墍浠ュ湪絎竴嬈¤鍙朧涔嬪悗浠ュ強(qiáng)瀵筕鎵цCAS鎿嶄綔涔嬪墠錛屽鏋滃皢鍊間粠A鏀逛負(fù)B錛岀劧鍚庡啀鏀瑰洖A錛屼細(xì)浣垮熀浜嶤AS鐨勭畻娉曟販涔便傚湪榪欑鎯呭喌涓嬶紝CAS鎿嶄綔浼?xì)鎴愬姛銆傝繖綾婚棶棰樼О涓篈BA闂銆?/p>

Wiki Hazard Pointer鎻愬埌浜?jiǎn)涓涓狝BA闂鐨勫ソ渚嬪瓙錛氬湪涓涓狶ock free鐨勬爤瀹炵幇涓紝鐜板湪瑕佸嚭鏍堬紝鏍堥噷鐨勫厓绱犳槸[A, B, C]錛?code>head鎸囧悜鏍堥《錛岄偅涔堝氨鏈?code>compare_and_swap(target=&head, newvalue=B, expected=A)銆備絾鏄湪榪欎釜鎿嶄綔涓紝鍏朵粬綰跨▼鎶?code>A B閮藉嚭鏍堬紝涓斿垹闄や簡(jiǎn)B錛屽張鎶?code>A鍘嬪叆鏍堜腑錛屽嵆[A, C]銆傞偅涔堝墠涓涓嚎紼嬬殑compare_and_swap鑳藉鎴愬姛錛屾鏃?code>head鎸囧悜浜?jiǎn)涓涓凡緇忚鍒犻櫎鐨?code>B銆俿tackoverflow涓婁篃鏈変釜渚嬪瓙 Real-world examples for ABA in multithreading

瀵逛簬CAS浜х敓鐨勮繖涓狝BA闂錛岄氬父鐨勮В鍐蟲(chóng)柟妗堟槸閲囩敤CAS鐨勪竴涓彉縐岲CAS銆侱CAS錛屾槸瀵逛簬姣忎竴涓猇澧炲姞涓涓紩鐢ㄧ殑琛ㄧず淇敼嬈℃暟鐨勬爣璁扮銆傚浜庢瘡涓猇錛屽鏋滃紩鐢ㄤ慨鏀逛簡(jiǎn)涓嬈★紝榪欎釜璁℃暟鍣ㄥ氨鍔?銆傜劧鍚庡啀榪欎釜鍙橀噺闇瑕乽pdate鐨勬椂鍊欙紝灝卞悓鏃舵鏌ュ彉閲忕殑鍊煎拰璁℃暟鍣ㄧ殑鍊箋?/p>

浣嗕篃鏃╂湁浜烘彁鍑?code>DCAS涔熶笉鏄?a >ABA problem 鐨勯摱寮?/a>銆?/p>



Kevin Lynx 2015-05-03 20:46 鍙戣〃璇勮
]]>
浣跨敤RCU鎶鏈疄鐜拌鍐欑嚎紼嬫棤閿?/title><link>http://m.shnenglu.com/kevinlynx/archive/2015/04/19/210386.html</link><dc:creator>Kevin Lynx</dc:creator><author>Kevin Lynx</author><pubDate>Sun, 19 Apr 2015 11:10:00 GMT</pubDate><guid>http://m.shnenglu.com/kevinlynx/archive/2015/04/19/210386.html</guid><wfw:comment>http://m.shnenglu.com/kevinlynx/comments/210386.html</wfw:comment><comments>http://m.shnenglu.com/kevinlynx/archive/2015/04/19/210386.html#Feedback</comments><slash:comments>3</slash:comments><wfw:commentRss>http://m.shnenglu.com/kevinlynx/comments/commentRss/210386.html</wfw:commentRss><trackback:ping>http://m.shnenglu.com/kevinlynx/services/trackbacks/210386.html</trackback:ping><description><![CDATA[<div id="hvzpftn" class="entry-content"> <p>鍦ㄤ竴涓郴緇熶腑鏈変竴涓啓綰跨▼鍜岃嫢騫蹭釜璇葷嚎紼嬶紝璇誨啓綰跨▼閫氳繃涓涓寚閽堝叡鐢ㄤ簡(jiǎn)涓涓暟鎹粨鏋勶紝鍐欑嚎紼嬫敼鍐欒繖涓粨鏋勶紝璇葷嚎紼嬭鍙栬緇撴瀯銆傚湪鍐欑嚎紼嬫敼鍐欒繖涓暟鎹粨鏋勭殑榪囩▼涓紝鍔犻攣鎯呭喌涓嬭綰跨▼鐢變簬絳夊緟閿佽楁椂浼?xì)澧炲姞銆?/p> <p>鍙互鍒╃敤RCU (Read Copy Update <a >What is rcu</a>)鐨勬濇兂鏉ュ幓闄よ繖涓攣銆傛湰鏂囨彁鍒扮殑涓昏瀹炵幇浠g爜錛?a >gist</a></p> <h2>RCU</h2> <p>RCU鍙互璇存槸涓縐嶆浛浠h鍐欓攣鐨勬柟娉曘傚叾鍩轟簬涓涓簨瀹烇細(xì)褰撳啓綰跨▼鍦ㄦ敼鍙樹(shù)竴涓寚閽堟椂錛岃綰跨▼鑾峰彇榪欎釜鎸囬拡錛岃涔堣幏鍙栧埌鑰佺殑鍊鹼紝瑕佷箞鑾峰彇鍒版柊鐨勫箋俁CU鐨勫熀鏈濇兂鍏跺疄寰堢畝鍗曪紝鍙傝?a >What is RCU</a>涓璗oy implementation鍙互寰堝鏄撶悊瑙c備竴縐嶇畝鍗曠殑RCU嫻佺▼鍙互鎻忚堪涓猴細(xì)</p> <p>鍐欑嚎紼嬶細(xì)</p> <pre><code>old_ptr = _ptr tmp_ptr = copy(_ptr) // copy change(tmp_ptr) // change _ptr = tmp_ptr // update synchroize(tmp_ptr) </code></pre> <p>鍐欑嚎紼嬭鏇存柊<code>_ptr</code>鎸囧悜鐨勫唴瀹規(guī)椂錛屽厛澶嶅埗涓浠芥柊鐨勶紝鍩轟簬鏂扮殑榪涜鏀瑰彉錛屾洿鏂?code>_ptr</code>鎸囬拡錛屾渶鍚庡悓姝ラ噴鏀捐佺殑鍐呭瓨銆?/p> <!-- more --> <p>璇葷嚎紼嬶細(xì)</p> <pre><code>tmp_ptr = _ptr use(tmp_ptr) dereference(tmp_ptr) </code></pre> <p>璇葷嚎紼嬬洿鎺ヤ嬌鐢?code>_ptr</code>錛屼嬌鐢ㄥ畬鍚庨渶瑕佸憡璇夊啓綰跨▼鑷繁涓嶅啀浣跨敤<code>_ptr</code>銆傝綰跨▼鑾峰彇<code>_ptr</code>鏃訛紝鍙兘浼?xì)鑾峰彇鍒拌佺殑涔熷彲鑳借幏鍙栧埌鏂扮殑錛屾棤璁哄摢縐峈CU閮介渶瑕佷繚璇佽繖鍧楀唴瀛樻槸鏈夋晥鐨勩傞噸鐐瑰湪<code>synchroize</code>鍜?code>dereference</code>銆?code>synchroize</code>浼?xì)绛夊緟鎵鏈変嬌鐢ㄨ佺殑<code>_ptr</code>鐨勭嚎紼?code>dereference</code>錛屽浜庢柊鐨?code>_ptr</code>浣跨敤鑰呭叾涓嶉渶瑕佺瓑寰呫傝繖涓棶棰樿鐧戒簡(jiǎn)灝辨槸鍐欑嚎紼嬪浣曠煡閬?code>old_ptr</code>娌℃湁浠諱綍璇葷嚎紼嬪湪浣跨敤錛屽彲浠ュ畨鍏ㄥ湴閲婃斁銆?/p> <p>榪欎釜闂瀹為檯涓婂湪<code>wait-free</code>鐨勫悇縐嶅疄鐜頒腑鏈夊ソ浜涜В娉曪紝<a >how-when-to-release-memory-in-wait-free-algorithms</a>榪欓噷鏈変漢鎬葷粨浜?jiǎn)鍑牽U嶆柟娉曪紝渚嬪<code>Hazard pointers</code>銆?code>Quiescence period based reclamation</code>銆?/p> <p>綆鍗曞湴浣跨敤寮曠敤璁℃暟鏅鴻兘鎸囬拡鏄棤娉曡В鍐寵繖涓棶棰樼殑錛屽洜涓烘櫤鑳芥寚閽堣嚜宸變笉鏄嚎紼嬪畨鍏ㄧ殑錛屼緥濡傦細(xì)</p> <pre><code>tmp_ptr = _ptr // 1 tmp_ptr->addRef() // 2 use tmp_ptr->release() </code></pre> <p>浠g爜1/2琛屼笉鏄師瀛愮殑錛屾墍浠ュ綋鍙栧緱<code>tmp_ptr</code>鍑嗗<code>addRef</code>鏃訛紝<code>tmp_ptr</code>鍙兘鍒氬ソ琚噴鏀句簡(jiǎn)銆?/p> <p><code>Quiescence period based reclamation</code>鏂規(guī)硶鎸囩殑鏄綰跨▼闇瑕佸0鏄庤嚜宸卞浜?code>Quiescence period</code>錛屼篃灝辨槸涓嶄嬌鐢?code>_ptr</code>鐨勬椂鍊欙紝褰撳叾浣跨敤<code>_ptr</code>鐨勬椂鍊欏疄闄呮槸榪涘叆浜?jiǎn)涓涓昏緫涓婄殑涓寸晫鍖猴紝褰撴墍鏈夎綰跨▼閮戒笉鍐嶄嬌鐢?code>_ptr</code>鐨勬椂鍊欙紝鍐欑嚎紼嬪氨鍙互瀵瑰唴瀛樿繘琛屽畨鍏ㄥ湴閲婃斁銆?/p> <p>鏈枃姝f槸鎻忚堪浜?jiǎn)涓縐?code>Quiescence period based reclamation</code>瀹炵幇銆傝繖涓疄鐜板彲浠ョ敤浜庢湁涓涓啓綰跨▼鍜屽涓綰跨▼鍏辯敤鑻ュ共涓暟鎹殑鍦烘櫙銆?/p> <h2>瀹炵幇</h2> <p>璇ユ柟娉曟湰璐ㄤ笂鎶婃暟鎹悓姝ュ垎瑙d負(fù)鍩烘湰鐨勫唴瀛樺崟鍏冭鍐欍備嬌鐢ㄦ柟寮忎笂鍙弿榪頒負(fù)錛?/p> <p>璇葷嚎紼嬶細(xì)</p> <pre><code>tmp_ptr = _ptr use update() // 鏍囪瘑鑷繁涓嶅啀浣跨敤浠諱綍鍏變韓鏁版嵁 </code></pre> <p>鍐欑嚎紼嬶細(xì)</p> <pre><code>old_ptr = _ptr tmp_ptr = copy(_ptr) change(tmp_ptr) _ptr = tmp_ptr gc() defer_free(old_ptr) </code></pre> <p>浠ヤ笅鍏蜂綋鎻忚堪璇誨啓綰跨▼鐨勫疄鐜般?/p> <h3>鍐欑嚎紼?/h3> <p>鍐欑嚎紼嬭礋璐f爣璇嗗唴瀛橀渶瑕佽閲婃斁錛屼互鍙?qiáng)妫鏌ヤ綍鏃跺彲浠ョ湡姝i噴鏀懼唴瀛樸傚叾緇存姢浜?jiǎn)涓涓噴鏀懼唴瀛橀槦鍒楋細(xì)</p> <div id="hvzpftn" class="highlight"><pre><code class="language-c--" data-lang="c++"><span id="hvzpftn" class="kt">void</span> <span id="hvzpftn" class="o">*</span><span id="hvzpftn" class="n">_pending</span><span id="hvzpftn" class="p">[</span><span id="hvzpftn" class="mi">8</span><span id="hvzpftn" class="p">]</span> <span id="hvzpftn" class="kt">uint64_t</span> <span id="hvzpftn" class="n">_head</span><span id="hvzpftn" class="p">,</span> <span id="hvzpftn" class="n">_tail</span> <span id="hvzpftn" class="kt">void</span> <span id="hvzpftn" class="n">defer_free</span><span id="hvzpftn" class="p">(</span><span id="hvzpftn" class="kt">void</span> <span id="hvzpftn" class="o">*</span><span id="hvzpftn" class="n">p</span><span id="hvzpftn" class="p">)</span> <span id="hvzpftn" class="p">{</span> <span id="hvzpftn" class="n">_head</span> <span id="hvzpftn" class="o">++</span> <span id="hvzpftn" class="n">_pending</span><span id="hvzpftn" class="p">[</span><span id="hvzpftn" class="n">PENDING_POS</span><span id="hvzpftn" class="p">(</span><span id="hvzpftn" class="n">_head</span><span id="hvzpftn" class="p">)]</span> <span id="hvzpftn" class="o">=</span> <span id="hvzpftn" class="n">p</span> <span id="hvzpftn" class="p">}</span> <span id="hvzpftn" class="n">gc</span><span id="hvzpftn" class="p">()</span> <span id="hvzpftn" class="p">{</span> <span id="hvzpftn" class="k">for</span> <span id="hvzpftn" class="p">(</span><span id="hvzpftn" class="n">_tail</span> <span id="hvzpftn" class="o">-></span> <span id="hvzpftn" class="n">find_free_pos</span><span id="hvzpftn" class="p">())</span> <span id="hvzpftn" class="n">free</span><span id="hvzpftn" class="p">(</span><span id="hvzpftn" class="n">_pending</span><span id="hvzpftn" class="p">[</span><span id="hvzpftn" class="n">_tail</span><span id="hvzpftn" class="p">])</span> <span id="hvzpftn" class="p">}</span></code></pre></div> <p><code>find_free_pos</code>鎵懼埌涓涓彲閲婃斁鍐呭瓨?shù)綅缃Q屽湪<code>[_tail, find_free_pos())</code>榪欎釜鍖洪棿鍐呮墍鏈夊唴瀛樻槸鍙互瀹夊叏琚噴鏀劇殑銆?/p> <p>闃熷垪浣嶇疆<code>_head/_tail</code>涓鐩村澶э紝<code>PENDING_POS</code>灝辨槸瀵硅繖涓綅緗彇妯★紝闄愬畾鍦ㄩ槦鍒楀ぇ灝忚寖鍥村唴涔熸槸鍙鐨勶紝鏃犺鍝鏂瑰紡錛?code>_head</code>浠庨昏緫涓婅涓鐩?code>>=_tail</code>錛屼絾鍦ㄥ疄闄呬腑鍙兘灝忎簬<code>_tail</code>錛屾墍浠ュ疄鐜版椂涓嶄嬌鐢ㄥぇ灝忓垽瀹氾紝鑰屾槸錛?/p> <div id="hvzpftn" class="highlight"><pre><code class="language-c--" data-lang="c++"><span id="hvzpftn" class="n">gc</span><span id="hvzpftn" class="p">()</span> <span id="hvzpftn" class="p">{</span> <span id="hvzpftn" class="n">pos</span> <span id="hvzpftn" class="o">=</span> <span id="hvzpftn" class="n">find_free_pos</span><span id="hvzpftn" class="p">()</span> <span id="hvzpftn" class="k">while</span> <span id="hvzpftn" class="p">(</span><span id="hvzpftn" class="n">_tail</span> <span id="hvzpftn" class="o">!=</span> <span id="hvzpftn" class="n">pos</span><span id="hvzpftn" class="p">)</span> <span id="hvzpftn" class="p">{</span> <span id="hvzpftn" class="n">free</span><span id="hvzpftn" class="p">(</span><span id="hvzpftn" class="n">_pending</span><span id="hvzpftn" class="p">[</span><span id="hvzpftn" class="n">PENDING_POS</span><span id="hvzpftn" class="p">(</span><span id="hvzpftn" class="n">_tail</span><span id="hvzpftn" class="p">)])</span> <span id="hvzpftn" class="n">_tail</span> <span id="hvzpftn" class="o">++</span> <span id="hvzpftn" class="p">}</span> <span id="hvzpftn" class="p">}</span></code></pre></div> <h3>璇葷嚎紼?/h3> <p>璇葷嚎紼嬩笉鍐嶄嬌鐢ㄥ叡浜唴瀛樻椂錛屽氨鏍囪瘑鑷繁錛?/p> <div id="hvzpftn" class="highlight"><pre><code class="language-c--" data-lang="c++"><span id="hvzpftn" class="n">update</span><span id="hvzpftn" class="p">()</span> <span id="hvzpftn" class="p">{</span> <span id="hvzpftn" class="k">static</span> <span id="hvzpftn" class="n">__thread</span> <span id="hvzpftn" class="kt">int</span> <span id="hvzpftn" class="n">tid</span> <span id="hvzpftn" class="n">_tmark</span><span id="hvzpftn" class="p">[</span><span id="hvzpftn" class="n">tid</span><span id="hvzpftn" class="p">]</span> <span id="hvzpftn" class="o">=</span> <span id="hvzpftn" class="n">_head</span> <span id="hvzpftn" class="p">}</span></code></pre></div> <p>璇葷嚎紼嬬殑鐘舵佷細(xì)褰卞搷鍐欑嚎紼嬬殑鍥炴敹閫昏緫錛屽叾鐘舵佸垎涓猴細(xì)</p> <ul> <li>鍒濆</li> <li>媧昏穬錛屼細(xì)璋冪敤鍒?code>update</code> </li> <li>鏆傚仠錛屽叾浠栧湴鏂瑰悓姝ワ紝鎴栬鎸傝搗</li> <li>閫鍑?/li> </ul> <p>璇葷嚎紼嬪浜庢椿璺冪姸鎬佹椂錛屽畠浼?xì)涓嶆柇鍦版洿鏂拌嚜宸卞彲閲婃攽謫呭瓨?shù)綅緗?<code>_tmark[tid]</code>)銆傚啓綰跨▼媯(gè)鏌ユ墍鏈夎綰跨▼鐨?code>_tmark[tid]</code>錛?code>[_tail, min(_tmark[]))</code>鏄墍鏈夎綰跨▼閮戒笉鍐嶄嬌鐢ㄧ殑鍐呭瓨鍖洪棿錛屽彲浠ヨ瀹夊叏閲婃斁銆?/p> <div id="hvzpftn" class="highlight"><pre><code class="language-c--" data-lang="c++"><span id="hvzpftn" class="n">find_free_pos</span><span id="hvzpftn" class="p">()</span> <span id="hvzpftn" class="p">{</span> <span id="hvzpftn" class="n">min</span> <span id="hvzpftn" class="o">=</span> <span id="hvzpftn" class="n">MAX_INTEGER</span> <span id="hvzpftn" class="n">pos</span> <span id="hvzpftn" class="o">=</span> <span id="hvzpftn" class="mi">0</span> <span id="hvzpftn" class="k">for</span> <span id="hvzpftn" class="p">(</span><span id="hvzpftn" class="n">tid</span> <span id="hvzpftn" class="o">=</span> <span id="hvzpftn" class="mi">0</span><span id="hvzpftn" class="p">;</span> <span id="hvzpftn" class="n">tid</span> <span id="hvzpftn" class="o"><</span> <span id="hvzpftn" class="n">max_threads</span><span id="hvzpftn" class="p">;</span> <span id="hvzpftn" class="o">++</span><span id="hvzpftn" class="n">tid</span><span id="hvzpftn" class="p">)</span> <span id="hvzpftn" class="p">{</span> <span id="hvzpftn" class="n">tpos</span> <span id="hvzpftn" class="o">=</span> <span id="hvzpftn" class="n">_tmark</span><span id="hvzpftn" class="p">[</span><span id="hvzpftn" class="n">tid</span><span id="hvzpftn" class="p">]</span> <span id="hvzpftn" class="n">offset</span> <span id="hvzpftn" class="o">=</span> <span id="hvzpftn" class="n">tpos</span> <span id="hvzpftn" class="o">-</span> <span id="hvzpftn" class="n">tail</span> <span id="hvzpftn" class="k">if</span> <span id="hvzpftn" class="p">(</span><span id="hvzpftn" class="n">offset</span> <span id="hvzpftn" class="o"><</span> <span id="hvzpftn" class="n">min</span><span id="hvzpftn" class="p">)</span> <span id="hvzpftn" class="p">{</span> <span id="hvzpftn" class="n">min</span> <span id="hvzpftn" class="o">=</span> <span id="hvzpftn" class="n">offset</span> <span id="hvzpftn" class="n">pos</span> <span id="hvzpftn" class="o">=</span> <span id="hvzpftn" class="n">tpos</span> <span id="hvzpftn" class="p">}</span> <span id="hvzpftn" class="p">}</span> <span id="hvzpftn" class="k">return</span> <span id="hvzpftn" class="n">pos</span> <span id="hvzpftn" class="p">}</span></code></pre></div> <p>褰撹綰跨▼鏆傚仠鏃訛紝鍏?code>_tmark[tid]</code>鍙兘浼?xì)鍦ㄥ緢闀夸竴孌墊椂闂撮噷寰椾笉鍒版洿鏂幫紝姝ゆ椂浼?xì)闃患剭鍐櫨U跨▼閲婃斁鍐呭瓨銆傛墍浠ラ渶瑕佹柟娉曟潵鏍囪瘑璇葷嚎紼嬫槸鍚﹁繘鍏ユ殏鍋滅姸鎬併傞氳繃璁劇疆涓涓笂嬈¢噴鏀懼唴瀛樹(shù)綅緗?code>_tfreeds[tid]</code>錛屾爣璇嗘瘡涓嚎紼嬪綋鍓嶅唴瀛橀噴鏀懼埌鐨勪綅緗傚鏋滀竴涓嚎紼嬪浜庢殏鍋滅姸鎬佷簡(jiǎn)錛岄偅涔堝湪涓瀹氭椂闂村悗錛?code>_tfreeds[tid] == _tmark[tid]</code>銆傚湪鏌ユ壘鍙噴鏀句綅緗椂錛屽氨闇瑕佸拷鐣ユ殏鍋滅姸鎬佺殑璇葷嚎紼嬶細(xì)</p> <div id="hvzpftn" class="highlight"><pre><code class="language-c--" data-lang="c++"><span id="hvzpftn" class="n">find_free_pos</span><span id="hvzpftn" class="p">()</span> <span id="hvzpftn" class="p">{</span> <span id="hvzpftn" class="n">min</span> <span id="hvzpftn" class="o">=</span> <span id="hvzpftn" class="n">MAX_INTEGER</span> <span id="hvzpftn" class="n">pos</span> <span id="hvzpftn" class="o">=</span> <span id="hvzpftn" class="n">_head</span> <span id="hvzpftn" class="k">for</span> <span id="hvzpftn" class="p">(</span><span id="hvzpftn" class="n">tid</span> <span id="hvzpftn" class="o">=</span> <span id="hvzpftn" class="mi">0</span><span id="hvzpftn" class="p">;</span> <span id="hvzpftn" class="n">tid</span> <span id="hvzpftn" class="o"><</span> <span id="hvzpftn" class="n">max_threads</span><span id="hvzpftn" class="p">;</span> <span id="hvzpftn" class="o">++</span><span id="hvzpftn" class="n">tid</span><span id="hvzpftn" class="p">)</span> <span id="hvzpftn" class="p">{</span> <span id="hvzpftn" class="n">tpos</span> <span id="hvzpftn" class="o">=</span> <span id="hvzpftn" class="n">_tmark</span><span id="hvzpftn" class="p">[</span><span id="hvzpftn" class="n">tid</span><span id="hvzpftn" class="p">]</span> <span id="hvzpftn" class="k">if</span> <span id="hvzpftn" class="p">(</span><span id="hvzpftn" class="n">tpos</span> <span id="hvzpftn" class="o">==</span> <span id="hvzpftn" class="n">_tfreeds</span><span id="hvzpftn" class="p">[</span><span id="hvzpftn" class="n">tid</span><span id="hvzpftn" class="p">])</span> <span id="hvzpftn" class="k">continue</span> <span id="hvzpftn" class="n">offset</span> <span id="hvzpftn" class="o">=</span> <span id="hvzpftn" class="n">tpos</span> <span id="hvzpftn" class="o">-</span> <span id="hvzpftn" class="n">tail</span> <span id="hvzpftn" class="k">if</span> <span id="hvzpftn" class="p">(</span><span id="hvzpftn" class="n">offset</span> <span id="hvzpftn" class="o"><</span> <span id="hvzpftn" class="n">min</span><span id="hvzpftn" class="p">)</span> <span id="hvzpftn" class="p">{</span> <span id="hvzpftn" class="n">min</span> <span id="hvzpftn" class="o">=</span> <span id="hvzpftn" class="n">offset</span> <span id="hvzpftn" class="n">pos</span> <span id="hvzpftn" class="o">=</span> <span id="hvzpftn" class="n">tpos</span> <span id="hvzpftn" class="p">}</span> <span id="hvzpftn" class="p">}</span> <span id="hvzpftn" class="k">for</span> <span id="hvzpftn" class="p">(</span><span id="hvzpftn" class="n">tid</span> <span id="hvzpftn" class="o">=</span> <span id="hvzpftn" class="mi">0</span><span id="hvzpftn" class="p">;</span> <span id="hvzpftn" class="n">tid</span> <span id="hvzpftn" class="o"><</span> <span id="hvzpftn" class="n">max_threads</span><span id="hvzpftn" class="p">;</span> <span id="hvzpftn" class="o">++</span><span id="hvzpftn" class="n">tid</span><span id="hvzpftn" class="p">)</span> <span id="hvzpftn" class="p">{</span> <span id="hvzpftn" class="k">if</span> <span id="hvzpftn" class="p">(</span><span id="hvzpftn" class="n">_tfreeds</span><span id="hvzpftn" class="p">[</span><span id="hvzpftn" class="n">tid</span><span id="hvzpftn" class="p">]</span> <span id="hvzpftn" class="o">!=</span> <span id="hvzpftn" class="n">_tmark</span><span id="hvzpftn" class="p">[</span><span id="hvzpftn" class="n">tid</span><span id="hvzpftn" class="p">])</span> <span id="hvzpftn" class="n">_tfreeds</span><span id="hvzpftn" class="p">[</span><span id="hvzpftn" class="n">tid</span><span id="hvzpftn" class="p">]</span> <span id="hvzpftn" class="o">=</span> <span id="hvzpftn" class="n">pos</span> <span id="hvzpftn" class="p">}</span> <span id="hvzpftn" class="k">return</span> <span id="hvzpftn" class="n">pos</span> <span id="hvzpftn" class="p">}</span></code></pre></div> <p>浣嗘槸褰撴墍鏈夌嚎紼嬮兘澶勪簬鏆傚仠鐘舵佹椂錛屽啓綰跨▼鍙兘榪樺湪宸ヤ綔錛屼笂闈㈢殑瀹炵幇灝變細(xì)榪斿洖<code>_head</code>錛屾鏃跺啓綰跨▼渚濈劧鍙互姝e父閲婃斁鍐呭瓨銆?/p> <p><strong>灝忕粨</strong>錛岃鏂規(guī)硶鍘熺悊鍙敤涓嬪浘琛ㄧず錛?/p> <p><img src="http://codemacro.com/assets/res/rw_thread.png" alt="" /></p> <h3>綰跨▼鍔ㄦ佸鍔?鍑忓皯</h3> <p>濡傛灉璇葷嚎紼嬪彲鑳戒腑閫旈鍑猴紝涓斿姩鎬佸鍔狅紝閭d箞<code>_tmark[]</code>灝遍渶瑕佽澶嶇敤錛屾鏃剁嚎紼?code>tid</code>鐨勫垎閰嶈皟鏁翠負(fù)鍔ㄦ佺殑鍗沖彲錛?/p> <div id="hvzpftn" class="highlight"><pre><code class="language-c--" data-lang="c++"><span id="hvzpftn" class="k">class</span> <span id="hvzpftn" class="nc">ThreadIdPool</span> <span id="hvzpftn" class="p">{</span> <span id="hvzpftn" class="k">public</span><span id="hvzpftn" class="o">:</span> <span id="hvzpftn" class="c1">// 鍔ㄦ佽幏鍙栦竴涓嚎紼媡id錛屾煇綰跨▼姣忔璋冪敤璇ユ帴鍙h繑鍥炵浉鍚岀殑鍊?/span> <span id="hvzpftn" class="kt">int</span> <span id="hvzpftn" class="n">get</span><span id="hvzpftn" class="p">()</span> <span id="hvzpftn" class="c1">// 綰跨▼閫鍑烘椂鍥炴敹璇id</span> <span id="hvzpftn" class="kt">void</span> <span id="hvzpftn" class="n">put</span><span id="hvzpftn" class="p">(</span><span id="hvzpftn" class="kt">int</span> <span id="hvzpftn" class="n">id</span><span id="hvzpftn" class="p">)</span> <span id="hvzpftn" class="p">}</span></code></pre></div> <p><code>ThreadIdPool</code>鐨勫疄鐜版棤闈炲氨鏄埄鐢═LS錛屼互鍙?qiáng)鍦ňU跨▼閫鍑烘椂寰楀埌閫氱煡浠ュ洖鏀秚id銆傞偅涔堝浜庤綰跨▼鐨?code>update</code>瀹炵幇鍙樹(shù)負(fù)錛?/p> <div id="hvzpftn" class="highlight"><pre><code class="language-c--" data-lang="c++"><span id="hvzpftn" class="n">update</span><span id="hvzpftn" class="p">()</span> <span id="hvzpftn" class="p">{</span> <span id="hvzpftn" class="n">tid</span> <span id="hvzpftn" class="o">=</span> <span id="hvzpftn" class="n">_idPool</span><span id="hvzpftn" class="o">-></span><span id="hvzpftn" class="n">get</span><span id="hvzpftn" class="p">()</span> <span id="hvzpftn" class="n">_tmark</span><span id="hvzpftn" class="p">[</span><span id="hvzpftn" class="n">tid</span><span id="hvzpftn" class="p">]</span> <span id="hvzpftn" class="o">=</span> <span id="hvzpftn" class="n">_head</span> <span id="hvzpftn" class="p">}</span></code></pre></div> <p>褰撴煇涓嚎紼嬮鍑烘椂錛?code>_tmark[tid]</code>鍜?code>_tfreeds[tid]</code>涓嶉渶瑕佸仛浠諱綍澶勭悊錛屽綋鏂板垱寤虹殑綰跨▼澶嶇敤浜?jiǎn)璇?code>tid</code>鏃訛紝鍙互绔嬪嵆澶嶇敤<code>_tmark[tid]</code>鍜?code>_tfreeds[tid]</code>錛屾鏃惰繖2涓煎繀鐒舵槸鐩哥瓑鐨勩?/p> <p>浠ヤ笂錛屽氨鏄暣涓柟娉曠殑瀹炵幇銆?/p> <h2>綰跨▼鍙鍙啓</h2> <p>浠ヤ笂鏂規(guī)硶閫傜敤鍦烘櫙榪樻槸涓嶅閫氱敤銆傚湪<a >nbds</a>欏圭洰錛堝疄鐜頒簡(jiǎn)涓浜涙棤閿佹暟鎹粨鏋勭殑toy project錛変腑鏈変竴浠借櫧鐒剁畝鍗曚絾涔熸湁鍚彂鐨勫疄鐜?rcu.c)銆傝瀹炵幇鏀寔浠繪剰綰跨▼<code>defer_free</code>錛屾墍鏈夌嚎紼?code>update</code>銆?code>update</code>闄や簡(jiǎn)澹版槑涓嶅啀浣跨敤浠諱綍鍏變韓鍐呭瓨澶栵紝榪樺彲鑳藉洖鏀跺唴瀛樸備換鎰忕嚎紼嬮兘鍙兘緇存姢涓浜涘緟閲婃斁鐨勫唴瀛橈紝浠繪剰涓鍧楀唴瀛樺彲鑳借浠繪剰鍏朵粬綰跨▼浣跨敤銆傞偅涔堝畠鏄浣曞唴瀛樺洖鏀剁殑錛?/p> <p>鏈枃鎻忚堪鐨勬柟娉曟槸鎵鏈夎綰跨▼鑷繁澹版槑鑷繁錛岀劧鍚庣敱鍐欑嚎紼嬩富鍔ㄦ潵媯(gè)鏌ャ備笉鍚屼簬姝ゆ柟娉曪紝 nbds鐨勫疄鐜幫紝鍩轟簬涓縐?strong>閫氱煡鎵╂暎</strong>鐨勬柟寮忋傝鏂瑰紡浠ヨ繖鏍蜂竴縐嶆柟寮忓伐浣滐細(xì)</p> <p>褰撴煇涓嚎紼嬪皾璇曞唴瀛樺洖鏀舵椂錛屽畠闇瑕佺煡閬撴墍鏈夊叾浠栫嚎紼嬬殑絀洪棽浣嶇疆錛堢浉褰撲簬<code>_tmark[tid]</code>錛夛紝瀹冮氱煡涓嬩竴涓嚎紼嬫垜闇瑕侀噴鏀劇殑鑼冨洿銆傚綋涓嬩竴涓嚎紼?code>update</code>鏃訛紙紱誨紑涓寸晫鍖猴級(jí)錛屽畠浼?xì)灏嗕笂涓U跨▼鐨勯氱煡緇х畫(huà)鍛婅瘔涓嬩竴涓嚎紼嬶紝鐩村埌鏈鍚庤繖涓氱煡鍥炲埌鍙戣搗綰跨▼銆傞偅涔堝浜庡彂璧風(fēng)嚎紼嬭岃█錛岃繖涓噴鏀捐姹傚湪鎵鏈夌嚎紼嬩腑璧頒簡(jiǎn)涓閬嶏紝寰楀埌浜?jiǎn)澶у鐨勮鍙Q屽彲浠ュ畨鍏ㄩ噴鏀俱傛瘡涓嚎紼嬮兘浠ヨ繖鏍風(fēng)殑鏂瑰紡宸ヤ綔銆?/p> <div id="hvzpftn" class="highlight"><pre><code class="language-c--" data-lang="c++"><span id="hvzpftn" class="kt">void</span> <span id="hvzpftn" class="nf">rcu_defer_free</span> <span id="hvzpftn" class="p">(</span><span id="hvzpftn" class="kt">void</span> <span id="hvzpftn" class="o">*</span><span id="hvzpftn" class="n">x</span><span id="hvzpftn" class="p">)</span> <span id="hvzpftn" class="p">{</span> <span id="hvzpftn" class="p">...</span> <span id="hvzpftn" class="n">rcu_</span><span id="hvzpftn" class="p">[</span><span id="hvzpftn" class="n">next_thread_id</span><span id="hvzpftn" class="p">][</span><span id="hvzpftn" class="n">tid_</span><span id="hvzpftn" class="p">]</span> <span id="hvzpftn" class="o">=</span> <span id="hvzpftn" class="n">rcu_last_posted_</span><span id="hvzpftn" class="p">[</span><span id="hvzpftn" class="n">tid_</span><span id="hvzpftn" class="p">][</span><span id="hvzpftn" class="n">tid_</span><span id="hvzpftn" class="p">]</span> <span id="hvzpftn" class="o">=</span> <span id="hvzpftn" class="n">pending_</span><span id="hvzpftn" class="p">[</span><span id="hvzpftn" class="n">tid_</span><span id="hvzpftn" class="p">]</span><span id="hvzpftn" class="o">-></span><span id="hvzpftn" class="n">head</span><span id="hvzpftn" class="p">;</span> <span id="hvzpftn" class="p">...</span> <span id="hvzpftn" class="p">}</span> <span id="hvzpftn" class="kt">void</span> <span id="hvzpftn" class="nf">rcu_update</span> <span id="hvzpftn" class="p">(</span><span id="hvzpftn" class="kt">void</span><span id="hvzpftn" class="p">)</span> <span id="hvzpftn" class="p">{</span> <span id="hvzpftn" class="p">...</span> <span id="hvzpftn" class="k">for</span> <span id="hvzpftn" class="p">(</span><span id="hvzpftn" class="n">i</span> <span id="hvzpftn" class="o">=</span> <span id="hvzpftn" class="mi">0</span><span id="hvzpftn" class="p">;</span> <span id="hvzpftn" class="n">i</span> <span id="hvzpftn" class="o"><</span> <span id="hvzpftn" class="n">num_threads_</span><span id="hvzpftn" class="p">;</span> <span id="hvzpftn" class="o">++</span><span id="hvzpftn" class="n">i</span><span id="hvzpftn" class="p">)</span> <span id="hvzpftn" class="p">{</span> <span id="hvzpftn" class="p">...</span> <span id="hvzpftn" class="kt">uint64_t</span> <span id="hvzpftn" class="n">x</span> <span id="hvzpftn" class="o">=</span> <span id="hvzpftn" class="n">rcu_</span><span id="hvzpftn" class="p">[</span><span id="hvzpftn" class="n">tid_</span><span id="hvzpftn" class="p">][</span><span id="hvzpftn" class="n">i</span><span id="hvzpftn" class="p">];</span> <span id="hvzpftn" class="c1">// 鍏跺畠綰跨▼鍙戠粰鑷繁鐨勯氱煡</span> <span id="hvzpftn" class="n">rcu_</span><span id="hvzpftn" class="p">[</span><span id="hvzpftn" class="n">next_thread_id</span><span id="hvzpftn" class="p">][</span><span id="hvzpftn" class="n">i</span><span id="hvzpftn" class="p">]</span> <span id="hvzpftn" class="o">=</span> <span id="hvzpftn" class="n">rcu_last_posted_</span><span id="hvzpftn" class="p">[</span><span id="hvzpftn" class="n">tid_</span><span id="hvzpftn" class="p">][</span><span id="hvzpftn" class="n">i</span><span id="hvzpftn" class="p">]</span> <span id="hvzpftn" class="o">=</span> <span id="hvzpftn" class="n">x</span><span id="hvzpftn" class="p">;</span> <span id="hvzpftn" class="c1">// 鎵╂暎鍑哄幓</span> <span id="hvzpftn" class="p">...</span> <span id="hvzpftn" class="p">}</span> <span id="hvzpftn" class="p">...</span> <span id="hvzpftn" class="k">while</span> <span id="hvzpftn" class="p">(</span><span id="hvzpftn" class="n">q</span><span id="hvzpftn" class="o">-></span><span id="hvzpftn" class="n">tail</span> <span id="hvzpftn" class="o">!=</span> <span id="hvzpftn" class="n">rcu_</span><span id="hvzpftn" class="p">[</span><span id="hvzpftn" class="n">tid_</span><span id="hvzpftn" class="p">][</span><span id="hvzpftn" class="n">tid_</span><span id="hvzpftn" class="p">])</span> <span id="hvzpftn" class="p">{</span> <span id="hvzpftn" class="n">free</span> <span id="hvzpftn" class="p">}</span> <span id="hvzpftn" class="p">...</span> <span id="hvzpftn" class="p">}</span></code></pre></div> <p>榪欎釜瀹炵幇鐩稿綆鍗曪紝涓嶆敮鎸佺嚎紼嬫殏鍋滐紝浠ュ強(qiáng)綰跨▼鍔ㄦ佸鍔犲拰鍑忓皯銆?/p> <p class="post-footer"> 鍘熸枃鍦板潃錛? <a >http://codemacro.com/2015/04/19/rw_thread_gc/</a><br /> written by <a >Kevin Lynx</a>  posted at <a >http://codemacro.com</a> </p> </div><img src ="http://m.shnenglu.com/kevinlynx/aggbug/210386.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://m.shnenglu.com/kevinlynx/" target="_blank">Kevin Lynx</a> 2015-04-19 19:10 <a href="http://m.shnenglu.com/kevinlynx/archive/2015/04/19/210386.html#Feedback" target="_blank" style="text-decoration:none;">鍙戣〃璇勮</a></div>]]></description></item><item><title>璁頒竴嬈cmalloc鍒嗛厤鍐呭瓨寮曡搗鐨刢oredumphttp://m.shnenglu.com/kevinlynx/archive/2015/04/06/210257.htmlKevin LynxKevin LynxMon, 06 Apr 2015 10:33:00 GMThttp://m.shnenglu.com/kevinlynx/archive/2015/04/06/210257.htmlhttp://m.shnenglu.com/kevinlynx/comments/210257.htmlhttp://m.shnenglu.com/kevinlynx/archive/2015/04/06/210257.html#Feedback2http://m.shnenglu.com/kevinlynx/comments/commentRss/210257.htmlhttp://m.shnenglu.com/kevinlynx/services/trackbacks/210257.html

鐜拌薄

綰夸笂鐨勬湇鍔″嚭鐜癱oredump錛屽爢鏍堜負(fù)錛?/p>

#0  0x000000000045d145 in GetStackTrace(void**, int, int) ()
#1  0x000000000045ec22 in tcmalloc::PageHeap::GrowHeap(unsigned long) ()
#2  0x000000000045eeb3 in tcmalloc::PageHeap::New(unsigned long) ()
#3  0x0000000000459ee8 in tcmalloc::CentralFreeList::Populate() ()
#4  0x000000000045a088 in tcmalloc::CentralFreeList::FetchFromSpansSafe() ()
#5  0x000000000045a10a in tcmalloc::CentralFreeList::RemoveRange(void**, void**, int) ()
#6  0x000000000045c282 in tcmalloc::ThreadCache::FetchFromCentralCache(unsigned long, unsigned long) ()
#7  0x0000000000470766 in tc_malloc ()
#8  0x00007f75532cd4c2 in __conhash_get_rbnode (node=0x22c86870, hash=30)
        at build/release64/cm_sub/conhash/conhash_inter.c:88
#9  0x00007f75532cd76e in __conhash_add_replicas (conhash=0x24fbc7e0, iden=<value optimized out>)
        at build/release64/cm_sub/conhash/conhash_inter.c:45
#10 0x00007f75532cd1fa in conhash_add_node (conhash=0x24fbc7e0, iden=0) at build/release64/cm_sub/conhash/conhash.c:72
#11 0x00007f75532c651b in cm_sub::TopoCluster::initLBPolicyInfo (this=0x2593a400)
        at build/release64/cm_sub/topo_cluster.cpp:114
#12 0x00007f75532cad73 in cm_sub::TopoClusterManager::processClusterMapTable (this=0xa219e0, ref=0x267ea8c0)
        at build/release64/cm_sub/topo_cluster_manager.cpp:396
#13 0x00007f75532c5a93 in cm_sub::SubRespMsgProcess::reinitCluster (this=0x9c2f00, msg=0x4e738ed0)
        at build/release64/cm_sub/sub_resp_msg_process.cpp:157
...

鏌ョ湅浜?jiǎn)搴旂敤灞傜浉鍏虫暟鎹l撴瀯錛屽熀鏈暟鎹兘鏄病鏈夐棶棰樼殑銆傛墍浠ユ渶鍒濇鐤戞槸tcmalloc鍐呴儴緇存姢浜?jiǎn)閿欒鐨勫唴瀛樺Q屽湪鍒嗛厤鍐呭瓨鏃跺嚭閿欙紝榪欎釜鍫嗘爤鍙槸闂鐨勮〃璞°傚嚑澶╁悗錛岀嚎涓婄殑鍙︿竴涓湇鍔★紝鍩轟簬鍚屾牱鐨勫簱錛屼篃core浜?jiǎn)锛屽爢鏍垬q樻槸涓鏍風(fēng)殑銆?/p>

鏈鍒濆畾浣嶉棶棰橀兘鏄粠鏈榪戞洿鏂扮殑涓滆タ鍏ユ墜錛屽寘鎷緷璧栫殑server鐜錛屼絾閮芥病鏈夋槑鏄劇殑闂錛屾墍浠ユ渶鍚庡彧鑳戒粠core鐨勭洿鎺ュ師鍥犲叆鎵嬨?/p>

鍒嗘瀽GetStackTrace

紜core鐨勮緇嗕綅緗細(xì)

# core鍦ㄨ鎸囦護(hù)
0x000000000045d145 <_Z13GetStackTracePPvii+21>: mov    0x8(%rax),%r9

(gdb) p/x $rip              # core 鐨勬寚浠や綅緗?
$9 = 0x45d145
(gdb) p/x $rax              
$10 = 0x4e73aa58
(gdb) x/1a $rax+0x8         # rax + 8 = 0x4e73aa60
0x4e73aa60:     0x0

璇ユ寚浠ゅ皾璇曚粠[0x4e73aa60]澶勮鍙栧唴瀹癸紝鐒跺悗鍑洪敊錛岃繖涓唴瀛樺崟鍏冧笉鍙銆備絾鏄叿浣撹繖涓寚浠ゅ湪浠g爜涓槸浠涔堟剰鎬濓紝闇瑕佸皢榪欎釜鎸囦護(hù)瀵瑰簲鍒頒唬鐮佷腑銆傝幏鍙杢cmalloc鐨勬簮鐮侊紝鍙戠幇GetStackTrace鏍規(guī)嵁緙栬瘧閫夐」鏈夊緢澶氬疄鐜幫紝鎵浠ヨ繖閲岄夋嫨鏈鍙兘鐨勫疄鐜幫紝鐒跺悗瀵規(guī)瘮姹囩紪浠ョ‘璁や唬鐮佹槸鍚﹀尮閰嶃傛渶鍒濋夋嫨鐨勬槸stacktrace_x86-64-inl.h錛屽悗鏉ュ彂鐜板畬鍏ㄤ笉鍖歸厤錛屽張閫夋嫨浜?code>stacktrace_x86-inl.h銆傝繖涓疄鐜扮増鏈噷涔熸湁瀵?4浣嶅鉤鍙扮殑鏀寔銆?/p>

stacktrace_x86-inl.h閲屼嬌鐢ㄤ簡(jiǎn)涓浜涘畯鏉ョ敓鎴愬嚱鏁板悕鍜屽弬鏁幫紝綺劇畝鍚庝唬鐮佸ぇ姒備負(fù)錛?/p>

int GET_STACK_TRACE_OR_FRAMES {
      void **sp;
      unsigned long rbp;
      __asm__ volatile ("mov %%rbp, %0" : "=r" (rbp));
      sp = (void **) rbp;

      int n = 0;
      while (sp && n < max_depth) {
        if (*(sp+1) == reinterpret_cast<void *>(0)) {
          break;
        }
        void **next_sp = NextStackFrame<!IS_STACK_FRAMES, IS_WITH_CONTEXT>(sp, ucp);
        if (skip_count > 0) {
          skip_count--;
        } else {
          result[n] = *(sp+1);
          n++;
        }
        sp = next_sp;
      }
      return n;
    }

NextStackFrame鏄竴涓ā鏉垮嚱鏁幫紝鍖呭惈涓澶у爢浠g爜錛岀簿綆鍚庨潪甯哥畝鍗曪細(xì)

template<bool STRICT_UNWINDING, bool WITH_CONTEXT>
    static void **NextStackFrame(void **old_sp, const void *uc) {
      void **new_sp = (void **) *old_sp;
      if (STRICT_UNWINDING) {
        if (new_sp <= old_sp) return NULL;
        if ((uintptr_t)new_sp - (uintptr_t)old_sp > 100000) return NULL;
      } else {
        if (new_sp == old_sp) return NULL;
        if ((new_sp > old_sp)
            && ((uintptr_t)new_sp - (uintptr_t)old_sp > 1000000)) return NULL;
      }
      if ((uintptr_t)new_sp & (sizeof(void *) - 1)) return NULL;

      return new_sp;
    }

涓婇潰榪欎釜浠g爜鍒版眹緙栫殑瀵規(guī)瘮榪囩▼榪樻槸鑺變簡(jiǎn)浜涙椂闂達(dá)紝鍏朵腑姹囩紪涓嚭鐜扮殑涓浜涘父閲忓彲浠ュぇ澶х緝鐭姣旀椂闂達(dá)紝渚嬪涓婇潰鍑虹幇浜?code>100000錛屾眹緙栦腑灝辨湁錛?/p>

0x000000000045d176 <_Z13GetStackTracePPvii+70>: cmp    $0x186a0,%rbx  # 100000=0x186a0

娉ㄦ剰NextStackFrame涓殑 if (STRICT_UNWINDING)浣跨敤鐨勬槸妯℃澘鍙傛暟錛岃繖瀵艱嚧鐢熸垚鐨勪唬鐮佷腑鏍規(guī)湰娌℃湁else閮ㄥ垎錛屼篃灝辨病鏈?code>1000000榪欎釜甯擱噺

鍦ㄥ姣斾唬鐮佺殑榪囩▼涓紝鍙互鐭ラ亾鍏抽敭鐨勫嚑涓瘎瀛樺櫒銆佸唴瀛樹(shù)綅緗搴斿埌浠g爜涓殑鍙橀噺錛屼粠鑰屽彲浠ヨ繕鍘焎ore鏃剁殑鐜板満鐜銆傚垎鏋愯繃紼嬩腑涓嶄竴瀹氳浠庣涓琛屾眹緙栬錛屽彲浠ヤ粠杈冩槑鏄劇殑浣嶇疆璇伙紝浠庤岃繕鍘熸暣涓唬鐮侊紝鍑芥暟榪斿洖鎸囦護(hù)銆佽煩杞寚浠ゃ佹瘮杈冩寚浠ゃ佽鍐呭瓨鎸囦護(hù)銆佸弬鏁板瘎瀛樺櫒絳夐兘鏄瘮杈冩槑鏄懼搴旂殑鍦版柟銆?/p>

鍙﹀娉ㄦ剰GetStackTrace鍦?code>RecordGrowth涓皟鐢紝浼犲叆浜?涓弬鏁幫細(xì)

GetStackTrace(t->stack, kMaxStackDepth-1, 3); // kMaxStackDepth = 31

浠ヤ笅鏄垜鍒嗘瀽鐨勭畝鍗曟敞瑙o細(xì)

(gdb) disassemble
Dump of assembler code for function _Z13GetStackTracePPvii:
0x000000000045d130 <_Z13GetStackTracePPvii+0>:  push   %rbp
0x000000000045d131 <_Z13GetStackTracePPvii+1>:  mov    %rsp,%rbp
0x000000000045d134 <_Z13GetStackTracePPvii+4>:  push   %rbx
0x000000000045d135 <_Z13GetStackTracePPvii+5>:  mov    %rbp,%rax
0x000000000045d138 <_Z13GetStackTracePPvii+8>:  xor    %r8d,%r8d
0x000000000045d13b <_Z13GetStackTracePPvii+11>: test   %rax,%rax
0x000000000045d13e <_Z13GetStackTracePPvii+14>: je     0x45d167 <_Z13GetStackTracePPvii+55>
0x000000000045d140 <_Z13GetStackTracePPvii+16>: cmp    %esi,%r8d        # while ( .. max_depth > n ?
0x000000000045d143 <_Z13GetStackTracePPvii+19>: jge    0x45d167 <_Z13GetStackTracePPvii+55>
0x000000000045d145 <_Z13GetStackTracePPvii+21>: mov    0x8(%rax),%r9    # 鍏抽敭浣嶇疆錛?(sp+1) -> r9, rax 瀵瑰簲 sp鍙橀噺
0x000000000045d149 <_Z13GetStackTracePPvii+25>: test   %r9,%r9          # *(sp+1) == 0 ?
0x000000000045d14c <_Z13GetStackTracePPvii+28>: je     0x45d167 <_Z13GetStackTracePPvii+55>
0x000000000045d14e <_Z13GetStackTracePPvii+30>: mov    (%rax),%rcx      # new_sp = *old_sp錛岃繖閲屽凡緇忔槸NextStackFrame鐨勪唬鐮?
0x000000000045d151 <_Z13GetStackTracePPvii+33>: cmp    %rcx,%rax        # new_sp <= old_sp ? 
0x000000000045d154 <_Z13GetStackTracePPvii+36>: jb     0x45d170 <_Z13GetStackTracePPvii+64>  # new_sp > old_sp 璺寵漿
0x000000000045d156 <_Z13GetStackTracePPvii+38>: xor    %ecx,%ecx
0x000000000045d158 <_Z13GetStackTracePPvii+40>: test   %edx,%edx        # skip_count > 0 ?
0x000000000045d15a <_Z13GetStackTracePPvii+42>: jle    0x45d186 <_Z13GetStackTracePPvii+86>
0x000000000045d15c <_Z13GetStackTracePPvii+44>: sub    $0x1,%edx        # skip_count--
0x000000000045d15f <_Z13GetStackTracePPvii+47>: mov    %rcx,%rax        
0x000000000045d162 <_Z13GetStackTracePPvii+50>: test   %rax,%rax        # while (sp ?
0x000000000045d165 <_Z13GetStackTracePPvii+53>: jne    0x45d140 <_Z13GetStackTracePPvii+16>
0x000000000045d167 <_Z13GetStackTracePPvii+55>: pop    %rbx
0x000000000045d168 <_Z13GetStackTracePPvii+56>: leaveq 
0x000000000045d169 <_Z13GetStackTracePPvii+57>: mov    %r8d,%eax        # r8 瀛樺偍浜?jiǎn)杩斿洖鍊鹼紝r8=n
0x000000000045d16c <_Z13GetStackTracePPvii+60>: retq                    # return n
0x000000000045d16d <_Z13GetStackTracePPvii+61>: nopl   (%rax)
0x000000000045d170 <_Z13GetStackTracePPvii+64>: mov    %rcx,%rbx        
0x000000000045d173 <_Z13GetStackTracePPvii+67>: sub    %rax,%rbx        # offset = new_sp - old_sp
0x000000000045d176 <_Z13GetStackTracePPvii+70>: cmp    $0x186a0,%rbx    # offset > 100000 ?
0x000000000045d17d <_Z13GetStackTracePPvii+77>: ja     0x45d156 <_Z13GetStackTracePPvii+38> # return NULL
0x000000000045d17f <_Z13GetStackTracePPvii+79>: test   $0x7,%cl         # new_sp & (sizeof(void*) - 1)
0x000000000045d182 <_Z13GetStackTracePPvii+82>: je     0x45d158 <_Z13GetStackTracePPvii+40>
0x000000000045d184 <_Z13GetStackTracePPvii+84>: jmp    0x45d156 <_Z13GetStackTracePPvii+38>
0x000000000045d186 <_Z13GetStackTracePPvii+86>: movslq %r8d,%rax        # rax = n
0x000000000045d189 <_Z13GetStackTracePPvii+89>: add    $0x1,%r8d        # n++
0x000000000045d18d <_Z13GetStackTracePPvii+93>: mov    %r9,(%rdi,%rax,8)# 鍏抽敭浣嶇疆錛歳esult[n] = *(sp+1)
0x000000000045d191 <_Z13GetStackTracePPvii+97>: jmp    0x45d15f <_Z13GetStackTracePPvii+47>

鍒嗘瀽榪囩▼姣旇緝鑰楁椂錛屽悓鏃惰繕鍙互鍒嗘瀽涓?code>GetStackTrace鍑芥暟鐨勫疄鐜板師鐞嗭紝鍏跺疄灝辨槸鍒╃敤RBP瀵勫瓨鍣ㄤ笉鏂洖婧紝浠庤屽緱鍒版暣涓皟鐢ㄥ爢鏍堝悇涓嚱鏁扮殑鍦板潃錛堜弗鏍兼潵璇存槸榪斿洖鍦板潃錛夈傜畝鍗曠ず鎰忎笅鍑芥暟璋冪敤涓璕BP鐨勬儏鍐碉細(xì)

   ...
saved registers          # i.e push rbx
local variabes           # i.e sub 0x10, rsp
return address           # call xxx
last func RBP            # push rbp; mov rsp, rbp
saved registers
local variables 
return address
last func RBP
...                      # rsp

鎬諱箣錛?strong>涓鑸儏鍐典笅錛屼換浣曚竴涓嚱鏁頒腑錛孯BP瀵勫瓨鍣ㄦ寚鍚戜簡(jiǎn)褰撳墠鍑芥暟鐨勬爤鍩哄潃錛岃鏍堝熀鍧涓張瀛樺偍浜?jiǎn)璋冪敤鑰呯殑鏍堝熀鍧錛屽悓鏃惰鏍堝熀鍧鍓嶉潰榪樺瓨鍌ㄤ簡(jiǎn)璋冪敤鑰呯殑榪斿洖鍦板潃銆傛墍浠ワ紝GetStackTrace鐨勫疄鐜幫紝綆鍗曟潵璇村ぇ姒傚氨鏄細(xì)

sp = rbp  // 鍙栧緱褰撳墠鍑芥暟GetStackTrace鐨勬爤鍩哄潃
    while (n < max_depth) {
        new_sp = *sp
        result[n] = *(new_sp+1)
        n++
    }

浠ヤ笂錛屾渶緇堝氨鐭ラ亾浜?jiǎn)浠ヤ笅鍏抽敭淇℃伅锛?xì)

  • r8 瀵瑰簲鍙橀噺 n錛岃〃紺哄綋鍓嶅彇鍒扮鍑犱釜鏍堝撫浜?/li>
  • rax 瀵瑰簲鍙橀噺 sp錛屼唬鐮乧ore鍦?*(sp+1)
  • rdi 瀵瑰簲鍙橀噺 result錛岀敤浜庡瓨鍌ㄥ彇寰楃殑鍚勪釜鍦板潃

鐒跺悗鍙互鐪嬬湅鐜板満鏄庢牱鐨勶細(xì)

(gdb) x/10a $rdi
0x1ffc9b98:     0x45a088 <_ZN8tcmalloc15CentralFreeList18FetchFromSpansSafeEv+40>       0x45a10a <_ZN8tcmalloc15CentralFreeList11RemoveRangeEPPvS2_i+106>
0x1ffc9ba8:     0x45c282 <_ZN8tcmalloc11ThreadCache21FetchFromCentralCacheEmm+114>      0x470766 <tc_malloc+790>
0x1ffc9bb8:     0x7f75532cd4c2 <__conhash_get_rbnode+34>        0x0
0x1ffc9bc8:     0x0     0x0
0x1ffc9bd8:     0x0     0x0

(gdb) p/x $r8
$3 = 0x5

(gdb) p/x $rax
$4 = 0x4e73aa58

灝忕粨錛?/strong>

GetStackTrace鍦ㄥ彇璋冪敤__conhash_get_rbnode鐨勫嚱鏁版椂鍑洪敊錛屽彇寰椾簡(jiǎn)5涓嚱鏁板湴鍧銆傚綋鍓嶄嬌鐢ㄧ殑RBP涓?code>0x4e73aa58銆?/p>

閿欒鐨凴BP

RBP涔熸槸浠庡爢鏍堜腑鍙栧嚭鏉ョ殑錛屾棦鐒惰繖涓湴鍧鏈夐棶棰橈紝棣栧厛鎯沖埌鐨勫氨鏄湁浠g爜灞閮ㄥ彉閲?鏁扮粍鍐欒秺鐣屻備緥濡?code>sprintf鐨勪嬌鐢ㄣ傝屼笖錛?strong>涓鑸啓瓚婄晫鐮村潖鍫嗘爤錛岄兘鍙兘鏄妸璋冪敤鑰呯殑鍫嗘爤鐮村潖浜?/strong>錛屼緥濡傦細(xì)

char s[32];
memcpy(s, p, 1024);

鍥犱負(fù)鍐欏叆閮芥槸浠庝綆鍦板潃寰楂樺湴鍧鍐欙紝鑰岃皟鐢ㄨ呯殑鍫嗘爤鍦ㄩ珮鍦板潃銆傚綋鐒?dòng)灱屼篃浼?xì)閬囧埌鍐欏潖璋冪敤鑰呯殑璋冪敤鑰呯殑鍫嗘爤錛屼篃灝辨槸璺ㄦ爤甯ц秺鐣屽啓錛屼緥濡備互鍓嶉亣鍒扮殑錛?/p>

len = vsnprintf(buf, sizeof(buf), fmt, wtf-long-string);
buf[len] = 0;

__conhash_get_rbnode鐨凴BP鏄湪tcmalloc鐨勫爢鏍堜腑鍙栫殑錛?/p>

(gdb) f 7
#7  0x0000000000470766 in tc_malloc ()
(gdb) x/10a $rsp
0x4e738b80:     0x4e73aa58      0x22c86870
0x4e738b90:     0x4e738bd0      0x85
0x4e738ba0:     0x4e73aa58      0x7f75532cd4c2 <__conhash_get_rbnode+34>   # 0x4e73aa58

鎵浠ヨ繖閲屽氨浼?xì)鎬鐤戞槸tcmalloc榪欎釜鍑芥暟閲屾湁鎶婂爢鏍堢牬鍧忥紝榪欎釜鏃跺欏氨鏄浠g爜錛岀湅鐪嬫湁娌℃湁鐤戜技鍗遍櫓鐨勫湴鏂癸紝鏈灉銆傝繖閲屽氨闄峰叆浜?jiǎn)鍍靛眬錛屾鐤戝張閬囧埌浜?jiǎn)璺ㄦ爤鍝徵牬鍧忕殑鎯呭喌锛寴q欎釜鏃跺欏氨鍙兘__conhash_get_rbnode璋冪敤鏍堜腑鍛ㄥ洿鐨勫嚱鏁扮炕緲伙紝渚嬪璋冪敤__conhash_get_rbnode鐨勫嚱鏁?code>__conhash_add_replicas涓伆濂芥湁瀛楃涓叉搷浣滐細(xì)

void __conhash_add_replicas(conhash_t *conhash, int32_t iden)
    {
        node_t* node = __conhash_create_node(iden, conhash->replica);
        ...
        char buf[buf_len]; // buf_len = 64
        ...
        snprintf(buf, buf_len, VIRT_NODE_HASH_FMT, node->iden, i);
        uint32_t hash = conhash->cb_hashfunc(buf);
        if(util_rbtree_search(&(conhash->vnode_tree), hash) == NULL)
        {
            util_rbtree_node_t* rbnode = __conhash_get_rbnode(node, hash);
            ...

榪欐浠g爜鏈緇堝彂鐜版槸娌℃湁闂鐨勶紝榪欓噷鍙堣楄垂浜?jiǎn)涓崬畱鏃堕棿銆傚悗鏉ュ彂鐜拌嫢騫蹭釜鍑芥暟閲岀殑RBP閮芥湁鐐瑰鎬紝榪欎釜璋冪敤鏍堟瘮杈冩甯哥殑鑼冨洿鏄細(xì)0x4e738c90

(gdb) f 8
#8  0x00007f75532cd4c2 in __conhash_get_rbnode (node=0x22c86870, hash=30)
(gdb) p/x $rbp
$6 = 0x4e73aa58     # 榪欎釜榪樹(shù)笉綆楃壒鍒彲鐤?
(gdb) f 9
#9  0x00007f75532cd76e in __conhash_add_replicas (conhash=0x24fbc7e0, iden=<value optimized out>)
(gdb) p/x $rbp
$7 = 0x4e738c60     # 榪欎釜涔熶笉綆楃壒鍒彲鐤?
(gdb) f 10
#10 0x00007f75532cd1fa in conhash_add_node (conhash=0x24fbc7e0, iden=0) at build/release64/cm_sub/conhash/conhash.c:72
(gdb) p/x $rbp      # 鍙枒
$8 = 0x0
(gdb) f 11
#11 0x00007f75532c651b in cm_sub::TopoCluster::initLBPolicyInfo (this=0x2593a400)
(gdb) p/x $rbp      # 鍙枒
$9 = 0x2598fef0

涓轟粈涔堝緢澶氬嚱鏁頒腑RBP閮界湅璧鋒潵涓嶆甯革紵 鎯充簡(jiǎn)鎯崇湡瑕佹槸浠g爜閲屾妸鍫嗘爤鐮村潖浜?jiǎn)锛寴q欓敊璇緱鍙戠敓寰楀宸у錛?/p>

閿欒RBP鐨勬潵婧?/h2>

鐒跺悗杞満鏉ヤ簡(jiǎn)錛岃剳嫻蜂腑紿佺劧闂嚭-fomit-frame-pointer銆傜紪璇戝櫒鐢熸垚鐨勪唬鐮佷腑鏄彲浠ヤ笉闇瑕佹爤鍩哄潃鎸囬拡鐨勶紝涔熷氨鏄疪BP瀵勫瓨鍣ㄤ笉浣滀負(fù)鏍堝熀鍧瀵勫瓨鍣ㄣ傚ぇ閮ㄥ垎鍑芥暟鎴栬呰寮鍚簡(jiǎn)frame-pointer鐨勫嚱鏁幫紝鍏跺嚱鏁板ご閮戒細(xì)鏈変互涓嬫寚浠わ細(xì)

push   %rbp
mov    %rsp,%rbp
...

琛ㄧず淇濆瓨璋冪敤鑰呯殑鏍堝熀鍧鍒版爤涓紝浠ュ強(qiáng)璁劇疆鑷繁鐨勬爤鍩哄潃銆傜湅涓?code>__conhash緋誨垪鍑芥暟錛?/p>

Dump of assembler code for function __conhash_get_rbnode:
0x00007f75532cd4a0 <__conhash_get_rbnode+0>:    mov    %rbx,-0x18(%rsp)
0x00007f75532cd4a5 <__conhash_get_rbnode+5>:    mov    %rbp,-0x10(%rsp)
...

榪欎釜搴撴槸鍗曠嫭緙栬瘧鐨勶紝娌℃湁鏄劇ず鎸囧畾-fno-omit-frame-pointer錛屾煡闃?a >gcc鎵嬪唽錛宱2浼樺寲鏄紑鍚簡(jiǎn)omit-frame-pinter 鐨勩?/p>

鍦ㄦ病鏈塕BP鐨勬儏鍐典笅錛宼cmalloc鐨?code>GetStackTrace灝濊瘯璇籖BP鍙栬幏鍙栬皟鐢ㄨ繑鍥炲湴鍧錛岃嚜鐒舵槸鏈夐棶棰樼殑銆備絾鏄紝濡傛灉鏁翠釜璋冪敤鏍堜腑鐨勫嚱鏁幫紝瑕佷箞鏈塕BP錛岃涔堟病鏈塕BP錛岄偅涔?code>GetStackTrace鍙栧嚭鐨勭粨鏋滄渶澶氬氨鏄煩榪囦竴浜涙爤甯э紝涓嶄細(xì)鍑洪敊銆?/strong> 闄ら潪錛岃繖涓棿鐨勬煇涓嚱鏁版妸RBP瀵勫瓨鍣ㄥ彟浣滀粬鐢紙緙栬瘧鍣ㄧ渷鍑?guó)櫩欎釜瀵勫瓨鍣ㄨ偗瀹氭槸瑕佸彟浣滀粬鐢ㄧ殑锛?jí)銆傛墍浠ヨ繖閲岀戶緇拷鏌ヨ繖涓敊璇湴鍧0x4e73aa58鐨勬潵婧愩?/p>

鏉ユ簮宸茬粡姣旇緝鏄庢樉錛岃偗瀹氭槸__conhash_get_rbnode涓緗殑錛屽洜涓鴻繖涓嚱鏁扮殑RBP鏄湪琚皟鐢ㄨ?code>tcmalloc涓繚瀛樼殑銆?/p>

Dump of assembler code for function __conhash_get_rbnode:
0x00007f75532cd4a0 <__conhash_get_rbnode+0>:    mov    %rbx,-0x18(%rsp)
0x00007f75532cd4a5 <__conhash_get_rbnode+5>:    mov    %rbp,-0x10(%rsp)
0x00007f75532cd4aa <__conhash_get_rbnode+10>:   mov    %esi,%ebp                    # 鏀瑰啓浜?jiǎn)RBP
0x00007f75532cd4ac <__conhash_get_rbnode+12>:   mov    %r12,-0x8(%rsp)
0x00007f75532cd4b1 <__conhash_get_rbnode+17>:   sub    $0x18,%rsp
0x00007f75532cd4b5 <__conhash_get_rbnode+21>:   mov    %rdi,%r12
0x00007f75532cd4b8 <__conhash_get_rbnode+24>:   mov    $0x30,%edi
0x00007f75532cd4bd <__conhash_get_rbnode+29>:   callq  0x7f75532b98c8 <malloc@plt>  # 璋冪敤tcmalloc錛屾眹緙栧埌榪欓噷鍗沖彲

榪欓噷鎵撳嵃RSI瀵勫瓨鍣ㄧ殑鍊煎彲鑳戒細(xì)琚瀵鹼紝鍥犱負(fù)浠諱綍鏃跺欐墦鍗板瘎瀛樺櫒鐨勫煎彲鑳介兘鏄敊鐨勶紝闄ら潪瀹冩湁琚樉紺轟繚瀛樸備笉榪囪繖閲屽彲浠ョ湅鍑篟SI鐨勫兼潵婧愪簬鍙傛暟(RSI瀵瑰簲絎簩涓弬鏁?錛?/p>

void __conhash_add_replicas(conhash_t *conhash, int32_t iden)
    {
        node_t* node = __conhash_create_node(iden, conhash->replica);
        ...
        char buf[buf_len]; // buf_len = 64
        ...
        snprintf(buf, buf_len, VIRT_NODE_HASH_FMT, node->iden, i);
        uint32_t hash = conhash->cb_hashfunc(buf); // hash鍊肩敱涓涓瓧絎︿覆鍝堝笇鍑芥暟璁$畻
        if(util_rbtree_search(&(conhash->vnode_tree), hash) == NULL)
        {
            util_rbtree_node_t* rbnode = __conhash_get_rbnode(node, hash);  // hash鍊?/span>
            ...

榪藉埌__conhash_add_replicas錛?/p>

0x00007f75532cd764 <__conhash_add_replicas+164>:        mov    %ebx,%esi    # 鏉ユ簮浜巖bx
0x00007f75532cd766 <__conhash_add_replicas+166>:        mov    %r15,%rdi
0x00007f75532cd769 <__conhash_add_replicas+169>:        callq  0x7f75532b9e48 <__conhash_get_rbnode@plt>

(gdb) p/x $rbx
$11 = 0x4e73aa58
(gdb) p/x hash
$12 = 0x4e73aa58      # 0x4e73aa58

鎵懼埌浜?code>0x4e73aa58鐨勬潵婧愩傝繖涓湴鍧鍊肩珶鐒舵槸涓涓瓧絎︿覆鍝堝笇綆楁硶綆楀嚭鏉ョ殑錛佽繖閲岃繕鍙互鐪嬬湅榪欎釜瀛楃涓茬殑鍐呭錛?/p>

(gdb) x/1s $rsp
0x4e738bd0:      "conhash-00000-00133"

榪欎釜紕夊牎鐨勫搱甯屽嚱鏁版槸conhash_hash_def銆?/p>

coredump鐨勬潯浠?/h2>

浠ヤ笂錛屾棦鐒跺彧瑕佹煇涓簱omit-frame-pointer錛岄偅tcmalloc灝卞彲鑳藉嚭閿欙紝涓轟粈涔堝彂鐢熺殑棰戠巼騫朵笉楂樺憿錛熻繖涓彲浠ュ洖鍒?code>GetStackTrace灝ゅ叾鏄?code>NextStackFrame鐨勫疄鐜幫紝鍏朵腑鍖呭惈浜?jiǎn)鍑犱釜鍚堟硶RBP鐨勫垽瀹氾細(xì)

if (new_sp <= old_sp) return NULL;  // 涓婁竴涓爤甯х殑RBP鑲畾姣斿綋鍓嶇殑澶?/span>
        if ((uintptr_t)new_sp - (uintptr_t)old_sp > 100000) return NULL; // 鎸囬拡鍊艱寖鍥磋繕蹇呴』鍦?00000鍐?/span>
        ...
    if ((uintptr_t)new_sp & (sizeof(void *) - 1)) return NULL; // 鐢變簬鏈韓淇濆瓨鐨勬槸鎸囬拡錛屾墍浠ヨ繕蹇呴』鏄痵izeof(void*)鐨勬暣鏁板嶏紝瀵歸綈

鏈変簡(jiǎn)浠ヤ笂鏉′歡錛屾墠浣垮緱榪欎釜core鍑犵巼鍙樺緱寰堜綆銆?/p>

鎬葷粨

鏈鍚庯紝濡傛灉浣犲緢鐔熸?zhèn)塼cmalloc錛屾暣涓棶棰樹(shù)及璁″氨琚瑙d簡(jiǎn)錛?a >tcmalloc INSTALL

闄?/h2>

鍙﹀闄勪笂鍙︿竴涓湁鎰忔濈殑涓滆タ銆?/p>

鍦ㄥ垎鏋?code>__conhash_add_replicas鏃訛紝鍏跺唴瀹氫箟浜?jiǎn)涓涓?4瀛楄妭鐨勫瓧絎︽暟緇勶紝鏌ョ湅鍏跺爢鏍堬細(xì)

(gdb) x/20a $rsp
0x4e738bd0:     0x2d687361686e6f63      0x30302d3030303030          # 榪欎簺鏄瓧絎︿覆conhash-00000-00133
0x4e738be0:     0x333331        0x0
0x4e738bf0:     0x0     0x7f75532cd69e <__conhash_create_node+78>
0x4e738c00:     0x24fbc7e0      0x4e738c60
0x4e738c10:     0x24fbc7e0      0x7f75532cd6e3 <__conhash_add_replicas+35>
0x4e738c20:     0x0     0x24fbc7e8
0x4e738c30:     0x4e738c20      0x24fbc7e0
0x4e738c40:     0x22324360      0x246632c0
0x4e738c50:     0x0     0x0
0x4e738c60:     0x0     0x7f75532cd1fa <conhash_add_node+74>

鏈寮濮嬫垜瑙夊緱buf鍗?4瀛楄妭錛屼篃灝辨槸鏁翠釜[0x4e738bd0, 0x4e738c10)鍐呭瓨錛屼絾鏄繖鍧楀唴瀛橀噷灞呯劧鏈夊嚱鏁板湴鍧錛岃繖涓搴︿嬌鎴戞鐤戣繖閲屾湁闂銆傚悗鏉ラ啋鎮(zhèn)熻繖浜涘湴鍧鏄畾涔?code>buf鍓嶈皟鐢?code>__conhash_create_node浜х敓鐨勶紝璋冪敤榪囩▼涓啓鍒板爢鏍堥噷錛岃皟鐢ㄥ畬鍚庢爤鎸囬拡鏀瑰彉錛屼絾騫朵笉闇瑕佹竻絀烘爤涓殑鍐呭銆?/p>



]]>鍩轟簬鍐呭瓨鏌ョ湅STL甯哥敤瀹瑰櫒鍐呭http://m.shnenglu.com/kevinlynx/archive/2014/12/03/209016.htmlKevin LynxKevin LynxWed, 03 Dec 2014 14:08:00 GMThttp://m.shnenglu.com/kevinlynx/archive/2014/12/03/209016.htmlhttp://m.shnenglu.com/kevinlynx/comments/209016.htmlhttp://m.shnenglu.com/kevinlynx/archive/2014/12/03/209016.html#Feedback2http://m.shnenglu.com/kevinlynx/comments/commentRss/209016.htmlhttp://m.shnenglu.com/kevinlynx/services/trackbacks/209016.html

鏈夋椂鍊欏湪綰夸笂浣跨敤gdb璋冭瘯紼嬪簭core闂鏃訛紝鍙兘娌℃湁絎﹀彿鏂囦歡錛屾嬁鍒扮殑浠呮槸涓涓唴瀛樺湴鍧錛屽鏋滆繖涓寚鍚戠殑鏄竴涓猄TL瀵硅薄錛岄偅涔堝浣曟煡鐪嬭繖涓璞$殑鍐呭鍛紵

鍙渶瑕佺煡閬揝TL鍚勪釜瀹瑰櫒鐨勬暟鎹粨鏋勫疄鐜幫紝灝卞彲浠ユ煡鐪嬪叾鍐呭銆傛湰鏂囨弿榪頒簡(jiǎn)SGI STL瀹炵幇涓父鐢ㄥ鍣ㄧ殑鏁版嵁緇撴瀯錛屼互鍙?qiáng)濡備綍鍦╣db涓煡鐪嬪叾鍐呭銆?/p>

string

string錛屽嵆basic_string bits/basic_string.h錛?/p>

mutable _Alloc_hider  _M_dataplus;
    ... 
      const _CharT*
      c_str() const
      { return _M_data(); }
    ...    
      _CharT*
      _M_data() const 
      { return  _M_dataplus._M_p; }

    ...
      struct _Alloc_hider : _Alloc
      {
    _Alloc_hider(_CharT* __dat, const _Alloc& __a)
    : _Alloc(__a), _M_p(__dat) { }

    _CharT* _M_p; // The actual data.
      };
   
      size_type
      length() const
      { return _M_rep()->_M_length; }

      _Rep*
      _M_rep() const
      { return &((reinterpret_cast<_Rep*> (_M_data()))[-1]); }

      ...
       struct _Rep_base
      {
    size_type       _M_length;
    size_type       _M_capacity;
    _Atomic_word        _M_refcount;
      };

      struct _Rep : _Rep_base

鍗籌紝string鍐呮湁涓涓寚閽堬紝鎸囧悜瀹為檯鐨勫瓧絎︿覆浣嶇疆錛岃繖涓綅緗墠闈㈡湁涓涓?code>_Rep緇撴瀯錛屽叾鍐呬繚瀛樹(shù)簡(jiǎn)瀛楃涓茬殑闀垮害銆佸彲鐢ㄥ唴瀛樹(shù)互鍙?qiáng)寮曠敤璁℃暟銆傚綋鎴戜滑鎷垮埌涓涓猻tring瀵硅薄鐨勫湴鍧鏃訛紝鍙互閫氳繃浠ヤ笅浠g爜鑾峰彇鐩稿叧鍊鹼細(xì)

void ds_str_i(void *p) {
        char **raw = (char**)p;
        char *s = *raw;
        size_t len = *(size_t*)(s - sizeof(size_t) * 3);
        printf("str: %s (%zd)\n", s, len);
    }

    size_t ds_str() {
        std::string s = "hello";
        ds_str_i(&s);
        return s.size();
    }

鍦╣db涓嬁鍒頒竴涓猻tring鐨勫湴鍧鏃訛紝鍙互浠ヤ笅鎵撳嵃鍑?guó)櫙ュ瓧绗︿覆鍙?qiáng)闀垮害錛?/p>

(gdb) x/1a p
0x7fffffffe3a0: 0x606028
(gdb) p (char*)0x606028
$2 = 0x606028 "hello"
(gdb) x/1dg 0x606028-24
0x606010:       5

vector

浼楁墍鍛ㄧ煡vector瀹炵幇灝辨槸涓鍧楄繛緇殑鍐呭瓨錛?code>bits/stl_vector.h銆?/p>

template<typename _Tp, typename _Alloc = std::allocator<_Tp> >
    class vector : protected _Vector_base<_Tp, _Alloc>

    ...
    template<typename _Tp, typename _Alloc>
    struct _Vector_base
    {
      typedef typename _Alloc::template rebind<_Tp>::other _Tp_alloc_type;

      struct _Vector_impl
      : public _Tp_alloc_type
      {
    _Tp*           _M_start;
    _Tp*           _M_finish;
    _Tp*           _M_end_of_storage;
    _Vector_impl(_Tp_alloc_type const& __a)
    : _Tp_alloc_type(__a), _M_start(0), _M_finish(0), _M_end_of_storage(0)
    { }
      };


      _Vector_impl _M_impl;

鍙互鐪嬪嚭sizeof(vector<xxx>)=24錛屽叾鍐呬篃灝辨槸3涓寚閽堬紝_M_start鎸囧悜棣栧厓绱犲湴鍧錛?code>_M_finish鎸囧悜鏈鍚庝竴涓妭鐐?1錛?code>_M_end_of_storage鏄彲鐢ㄧ┖闂存渶鍚庣殑浣嶇疆銆?/p>

iterator
      end()
      { return iterator (this->_M_impl._M_finish); }
      const_iterator
      ...
      begin() const
      { return const_iterator (this->_M_impl._M_start); }
      ...
      size_type
      capacity() const
      { return size_type(const_iterator(this->_M_impl._M_end_of_storage)
             - begin()); }

鍙互閫氳繃浠g爜浠庝竴涓獀ector瀵硅薄鍦板潃杈撳嚭鍏朵俊鎭細(xì)

template <typename T>
    void ds_vec_i(void *p) {
        T *start = *(T**)p;
        T *finish = *(T**)((char*)p + sizeof(void*));
        T *end_storage = *(T**)((char*)p + 2 * sizeof(void*));
        printf("vec size: %ld, avaiable size: %ld\n", finish - start, end_storage - start); 
    }

    size_t ds_vec() {
        std::vector<int> vec;
        vec.push_back(0x11);
        vec.push_back(0x22);
        vec.push_back(0x33);
        ds_vec_i<int>(&vec);
        return vec.size();
    }

浣跨敤gdb杈撳嚭涓涓獀ector涓殑鍐呭錛?/p>

(gdb) p p
$3 = (void *) 0x7fffffffe380
(gdb) x/1a p
0x7fffffffe380: 0x606080
(gdb) x/3xw 0x606080
0x606080:       0x00000011      0x00000022      0x00000033

list

浼楁墍鍛ㄧ煡list琚疄鐜頒負(fù)涓涓摼琛ㄣ傚噯紜潵璇存槸涓涓弻鍚戦摼琛ㄣ俵ist鏈韓鏄竴涓壒孌婅妭鐐癸紝鍏朵唬琛╡nd錛屽叾鎸囧悜鐨勪笅涓涓厓绱犳墠鏄痩ist鐪熸鐨勭涓涓妭鐐癸細(xì)

bits/stl_list.h

bool
      empty() const
      { return this->_M_impl._M_node._M_next == &this->_M_impl._M_node; }

      const_iterator
      begin() const
      { return const_iterator(this->_M_impl._M_node._M_next); }

      iterator
      end()
      { return iterator(&this->_M_impl._M_node); }

      ...

    struct _List_node_base
    {
        _List_node_base* _M_next;   ///< Self-explanatory
        _List_node_base* _M_prev;   ///< Self-explanatory
        ...
    };
         
    template<typename _Tp>
    struct _List_node : public _List_node_base
    {
      _Tp _M_data;                ///< User's data.
    };
      
    template<typename _Tp, typename _Alloc>
    class _List_base
    {
        ...
      struct _List_impl
      : public _Node_alloc_type
      {
    _List_node_base _M_node;
        ...
      };

      _List_impl _M_impl;

          
    template<typename _Tp, typename _Alloc = std::allocator<_Tp> >
    class list : protected _List_base<_Tp, _Alloc>

鎵浠?code>sizeof(list<xx>)=16錛屼袱涓寚閽堛傛瘡涓涓湡姝g殑鑺傜偣棣栧厛鏄寘鍚袱涓寚閽堬紝鐒跺悗鏄厓绱犲唴瀹?_List_node)銆?/p>

閫氳繃浠g爜杈撳嚭list鐨勫唴瀹癸細(xì)

#define NEXT(ptr, T) do { \
        void *n = *(char**)ptr; \
        T val = *(T*)((char**)ptr + 2); \
        printf("list item %p val: 0x%x\n", ptr, val); \
        ptr = n; \
    } while (0)

    template <typename T>
    void ds_list_i(void *p) {
        void *ptr = *(char**)p;

        NEXT(ptr, T);
        NEXT(ptr, T);
        NEXT(ptr, T);
    }

    size_t ds_list() {
        std::list<int> lst;
        lst.push_back(0x11);
        lst.push_back(0x22);
        lst.push_back(0x33);
        ds_list_i<int>(&lst);
        return lst.size();
    }

鍦╣db涓彲浠ヤ互涓嬫柟寮忛亶鍘嗚list錛?/p>

(gdb) p p
$4 = (void *) 0x7fffffffe390
(gdb) x/1a p
0x7fffffffe390: 0x606080
(gdb) x/1xw 0x606080+16         # 鍏冪礌1 
0x606090:       0x00000011
(gdb) x/1a 0x606080
0x606080:       0x6060a0
(gdb) x/1xw 0x6060a0+16         # 鍏冪礌2
0x6060b0:       0x00000022

map

map浣跨敤鐨勬槸綰㈤粦鏍?wèi)瀹炵帋图屽疄闄呬娇鐢ㄧ殑鏄?code>stl_tree.h瀹炵幇錛?/p>

bits/stl_map.h

typedef _Rb_tree<key_type, value_type, _Select1st<value_type>,
               key_compare, _Pair_alloc_type> _Rep_type;
    ...
     _Rep_type _M_t;
    ... 

      iterator
      begin()
      { return _M_t.begin(); }

bits/stl_tree.h

struct _Rb_tree_node_base
      {
        typedef _Rb_tree_node_base* _Base_ptr;
        typedef const _Rb_tree_node_base* _Const_Base_ptr;

        _Rb_tree_color  _M_color;
        _Base_ptr       _M_parent;
        _Base_ptr       _M_left;
        _Base_ptr       _M_right;
        
        ...
      };

    template<typename _Val>
    struct _Rb_tree_node : public _Rb_tree_node_base
    {
      typedef _Rb_tree_node<_Val>* _Link_type;
      _Val _M_value_field;
    };


    template<typename _Key_compare,
           bool _Is_pod_comparator = std::__is_pod<_Key_compare>::__value>
        struct _Rb_tree_impl : public _Node_allocator
        {
      _Key_compare      _M_key_compare;
      _Rb_tree_node_base    _M_header;
      size_type         _M_node_count; // Keeps track of size of tree.
      ...
        }
    
    _Rb_tree_impl<_Compare> _M_impl;
    ...

      iterator
      begin()
      {
    return iterator(static_cast<_Link_type>
            (this->_M_impl._M_header._M_left));
      }

鎵浠ュ彲浠ョ湅鍑猴紝澶ч儴鍒嗘椂鍊?鍙栧喅浜?code>_M_key_compare) sizeof(map<xx>)=48錛屼富瑕佺殑鍏冪礌鏄細(xì)

_Rb_tree_color  _M_color; // 鑺傜偣棰滆壊
        _Base_ptr       _M_parent; // 鐖惰妭鐐?/span>
        _Base_ptr       _M_left; // 宸﹁妭鐐?/span>
        _Base_ptr       _M_right; // 鍙寵妭鐐?/span>
        _Val            _M_value_field // 鍚宭ist涓妭鐐規(guī)妧宸т竴鑷達(dá)紝鍚庨潰鏄疄闄呯殑鍏冪礌

鍚宭ist涓殑瀹炵幇涓鑷達(dá)紝map鏈韓浣滀負(fù)涓涓妭鐐癸紝鍏朵笉鏄竴涓瓨鍌ㄦ暟鎹殑鑺傜偣錛?/p>

_Rb_tree::end

iterator
      end()
      { return iterator(static_cast<_Link_type>(&this->_M_impl._M_header)); }

鐢變簬鑺傜偣鍊煎湪_Rb_tree_node_base鍚庯紝鎵浠ヤ換鎰忔椂鍊欐嬁鍒拌妭鐐瑰氨鍙互鍋忕Щ榪欎釜緇撴瀯浣撴嬁鍒拌妭鐐瑰鹼紝鑺傜偣鐨勫兼槸涓涓猵air錛屽寘鍚簡(jiǎn)key鍜寁alue銆?/p>

鍦╣db涓墦鍗頒互涓媘ap鐨勫唴瀹癸細(xì)

size_t ds_map() {
        std::map<std::string, int> imap;
        imap["abc"] = 0xbbb;
        return imap.size();
    }
(gdb) p/x &imap
$7 = 0x7fffffffe370
(gdb) x/1a (char*)&imap+24       # _M_left 鐪熸鐨勮妭鐐?
0x7fffffffe388: 0x606040          
(gdb) x/1xw 0x606040+32+8        # 鍋忕Щ32瀛楄妭鏄妭鐐瑰肩殑鍦板潃錛屽啀鍋忕Щ8鍒欐槸value鐨勫湴鍧
0x606068:       0x00000bbb
(gdb) p *(char**)(0x606040+32)   # 鍋忕Щ32瀛楄妭鏄痵tring鐨勫湴鍧
$8 = 0x606028 "abc"

鎴栬呭緢澶氭椂鍊欐病鏈夊繀瑕佽繖涔堣閫?铔嬬柤錛?/p>

(gdb) p *(char**)(imap._M_t._M_impl._M_header._M_left+1)
$9 = 0x606028 "abc"
(gdb) x/1xw (char*)(imap._M_t._M_impl._M_header._M_left+1)+8
0x606068:       0x00000bbb

瀹?/em>



]]>
linux鍔ㄦ佸簱鐨勭縐嶈鐐?/title><link>http://m.shnenglu.com/kevinlynx/archive/2014/11/04/208761.html</link><dc:creator>Kevin Lynx</dc:creator><author>Kevin Lynx</author><pubDate>Mon, 03 Nov 2014 16:55:00 GMT</pubDate><guid>http://m.shnenglu.com/kevinlynx/archive/2014/11/04/208761.html</guid><wfw:comment>http://m.shnenglu.com/kevinlynx/comments/208761.html</wfw:comment><comments>http://m.shnenglu.com/kevinlynx/archive/2014/11/04/208761.html#Feedback</comments><slash:comments>1</slash:comments><wfw:commentRss>http://m.shnenglu.com/kevinlynx/comments/commentRss/208761.html</wfw:commentRss><trackback:ping>http://m.shnenglu.com/kevinlynx/services/trackbacks/208761.html</trackback:ping><description><![CDATA[<div id="hvzpftn" class="entry-content"> <p>linux涓嬩嬌鐢ㄥ姩鎬佸簱錛屽熀鏈敤璧鋒潵榪樻槸寰堝鏄撱備絾濡傛灉鎴戜滑鐨勭▼搴忎腑澶ч噺浣跨敤鍔ㄦ佸簱鏉ュ疄鐜板悇縐嶆鏋?鎻掍歡錛岄偅涔堝氨浼?xì)閬囧堫C竴浜涘潙錛屾帉鎻¤繖浜涘潙鎵嶆湁鍒╀簬紼嬪簭鏇寸ǔ鍋ュ湴榪愯銆?/p> <p>鏈瘒鍏堣皥璋堝姩鎬佸簱絎﹀彿鏂歸潰鐨勯棶棰樸?/p> <p>嫻嬭瘯浠g爜鍙互鍦?a >github涓婃壘鍒?/a></p> <h2>絎﹀彿鏌ユ壘</h2> <p>涓涓簲鐢ㄧ▼搴?code>test</code>浼?xì)閾炬帴涓涓姩鎬佸簱<code>libdy.so</code>錛屽鏋滀竴涓鍙鳳紝渚嬪鍑芥暟<code>callfn</code>瀹氫箟浜巐ibdy.so涓紝test瑕佷嬌鐢ㄨ鍑芥暟錛岀畝鍗曞湴澹版槑鍗沖彲錛?/p> <div id="hvzpftn" class="highlight"><pre><code class="language-c--" data-lang="c++"><span id="hvzpftn" class="c1">// dy.cpp libdy.so</span> <span id="hvzpftn" class="kt">void</span> <span id="hvzpftn" class="nf">callfn</span><span id="hvzpftn" class="p">()</span> <span id="hvzpftn" class="p">{</span> <span id="hvzpftn" class="p">...</span> <span id="hvzpftn" class="p">}</span> <span id="hvzpftn" class="c1">// main.cpp test</span> <span id="hvzpftn" class="k">extern</span> <span id="hvzpftn" class="kt">void</span> <span id="hvzpftn" class="nf">callfn</span><span id="hvzpftn" class="p">();</span> <span id="hvzpftn" class="n">callfn</span><span id="hvzpftn" class="p">();</span></code></pre></div> <p>鍦ㄩ摼鎺est鐨勬椂鍊欙紝閾炬帴鍣ㄤ細(xì)緇熶竴榪涜媯(gè)鏌ャ?/p> <p>鍚屾牱錛屽湪libdy.so涓湁鐩稿悓鐨勮鍒欙紝瀹冨彲浠ヤ嬌鐢ㄤ竴涓閮ㄧ殑絎﹀彿錛?strong>鍦ㄥ畠琚摼鎺?杞藉叆榪涗竴涓彲鎵ц紼嬪簭鏃舵墠浼?xì)杩涜绗﹀彿瀛樺湪涓庡惁鐨剫個(gè)鏌?/strong>銆傝繖涓鍙風(fēng)敋鑷沖彲浠ュ畾涔夊湪test涓紝褰㈡垚涓縐嶅弻鍚戜緷璧栵紝鎴栧畾涔夊湪鍏朵粬鍔ㄦ佸簱涓細(xì)</p> <!-- more --> <div id="hvzpftn" class="highlight"><pre><code class="language-c--" data-lang="c++"><span id="hvzpftn" class="c1">// dy.cpp libdy.so</span> <span id="hvzpftn" class="k">extern</span> <span id="hvzpftn" class="kt">void</span> <span id="hvzpftn" class="nf">mfunc</span><span id="hvzpftn" class="p">();</span> <span id="hvzpftn" class="n">mfunc</span><span id="hvzpftn" class="p">();</span> <span id="hvzpftn" class="c1">// main.cpp test</span> <span id="hvzpftn" class="kt">void</span> <span id="hvzpftn" class="nf">mfunc</span><span id="hvzpftn" class="p">()</span> <span id="hvzpftn" class="p">{</span> <span id="hvzpftn" class="p">...</span> <span id="hvzpftn" class="p">}</span></code></pre></div> <p>鍦ㄧ敓鎴恖ibdy.so鏃?code>mfunc</code>鍙互鎵句笉鍒幫紝姝ゆ椂<code>mfunc</code>涓烘湭瀹氫箟錛?/p> <pre><code>$ nm libdy.so | grep mfun U _Z5mfuncv </code></pre> <p>浣嗗湪libdy.so琚摼鎺ヨ繘test鏃跺垯浼?xì)杩涜妫鏌ワ紝璇曠潃鎶?code>mfunc</code>鍑芥暟鐨勫畾涔夊幓鎺夛紝灝變細(xì)寰楀埌涓涓摼鎺ラ敊璇細(xì)</p> <pre><code>./libdy.so: undefined reference to `mfunc()' </code></pre> <p>鍚屾牱錛屽鏋滄垜浠姩鎬佽澆鍏ibdy.so錛屾鏃跺綋鐒跺彲浠ラ摼鎺ラ氳繃錛屼絾鏄湪杞藉叆鏃跺悓鏍峰緱鍒版壘涓嶅埌絎﹀彿鐨勯敊璇細(xì)</p> <div id="hvzpftn" class="highlight"><pre><code class="language-c--" data-lang="c++"><span id="hvzpftn" class="cp">#ifdef DY_LOAD</span> <span id="hvzpftn" class="kt">void</span> <span id="hvzpftn" class="o">*</span><span id="hvzpftn" class="n">dp</span> <span id="hvzpftn" class="o">=</span> <span id="hvzpftn" class="n">dlopen</span><span id="hvzpftn" class="p">(</span><span id="hvzpftn" class="s">"./libdy.so"</span><span id="hvzpftn" class="p">,</span> <span id="hvzpftn" class="n">RTLD_LAZY</span><span id="hvzpftn" class="p">);</span> <span id="hvzpftn" class="k">typedef</span> <span id="hvzpftn" class="nf">void</span> <span id="hvzpftn" class="p">(</span><span id="hvzpftn" class="o">*</span><span id="hvzpftn" class="n">callfn</span><span id="hvzpftn" class="p">)();</span> <span id="hvzpftn" class="n">callfn</span> <span id="hvzpftn" class="n">f</span> <span id="hvzpftn" class="o">=</span> <span id="hvzpftn" class="p">(</span><span id="hvzpftn" class="n">callfn</span><span id="hvzpftn" class="p">)</span> <span id="hvzpftn" class="n">dlsym</span><span id="hvzpftn" class="p">(</span><span id="hvzpftn" class="n">dp</span><span id="hvzpftn" class="p">,</span> <span id="hvzpftn" class="s">"callfn"</span><span id="hvzpftn" class="p">);</span> <span id="hvzpftn" class="n">f</span><span id="hvzpftn" class="p">();</span> <span id="hvzpftn" class="n">dlclose</span><span id="hvzpftn" class="p">(</span><span id="hvzpftn" class="n">dp</span><span id="hvzpftn" class="p">);</span> <span id="hvzpftn" class="cp">#else</span> <span id="hvzpftn" class="n">callfn</span><span id="hvzpftn" class="p">();</span> <span id="hvzpftn" class="cp">#endif</span></code></pre></div> <p>寰楀埌閿欒錛?/p> <pre><code>./test: symbol lookup error: ./libdy.so: undefined symbol: _Z5mfuncv </code></pre> <p><strong>緇撹錛?/strong>鍩轟簬浠ヤ笂錛屾垜浠煡閬擄紝濡傛灉涓涓姩鎬佸簱渚濊禆浜?jiǎn)涓浜涘閮ㄧ鍙鳳紝榪欎簺澶栭儴絎﹀彿鍙互浣嶄簬鍏朵粬鍔ㄦ佸簱鐢氳嚦搴旂敤紼嬪簭涓傛垜浠彲浠ュ啀閾炬帴榪欎釜鍔ㄦ佸簱鐨勬椂鍊欏氨鎶婁緷璧栫殑鍏朵粬搴撲篃閾炬帴涓婏紝鎴栬呮帹榪熷埌閾炬帴搴旂敤紼嬪簭鏃跺啀閾炬帴銆傝屽姩鎬佸姞杞界殑搴擄紝鍒欒淇濊瘉鍦ㄥ姞杞借搴撴椂錛岃繘紼嬩腑鍔犺澆鐨勫叾浠栧姩鎬佸簱閲屽凡緇忓瓨鍦ㄨ絎﹀彿銆?/p> <p>渚嬪錛岄氳繃<code>LD_PRELOAD</code>鐜鍙橀噺鍙互璁╀竴涓繘紼嬪厛鍔犺澆鎸囧畾鐨勫姩鎬佸簱錛屼笂闈㈤偅涓姩鎬佸姞杞藉惎鍔ㄥけ璐ョ殑渚嬪瓙錛屽彲浠ラ氳繃棰勫厛鍔犺澆鍖呭惈<code>mfunc</code>絎﹀彿鐨勫姩鎬佸簱瑙e喅錛?/p> <pre><code>$ LD_PRELOAD=libmfun.so ./test ... </code></pre> <p>浣嗘槸濡傛灉榪欎釜絎﹀彿瀛樺湪浜庡彲鎵ц紼嬪簭涓垯涓嶈錛?/p> <pre><code>$ nm test | grep mfunc 0000000000400a00 T _Z5mfuncv $ nm test | grep mfunc 0000000000400a00 T _Z5mfuncv $ ./test ... ./test: symbol lookup error: ./libdy.so: undefined symbol: _Z5mfuncv </code></pre> <h2>絎﹀彿瑕嗙洊</h2> <p>鍓嶉潰涓昏璁茬殑鏄鍙風(fēng)己灝戠殑鎯呭喌錛屽鏋滃悓涓涓鍙峰瓨鍦ㄥ鍒嗭紝鍒欐洿鑳藉紩鍙戦棶棰樸傝繖閲岃皥鍒扮殑絎﹀彿閮芥槸鍏ㄥ眬絎﹀彿錛屼竴涓繘紼嬩腑鏌愪釜鍏ㄥ眬絎﹀彿濮嬬粓鏄叏灞鍞竴鐨勩備負(fù)浜?jiǎn)淇濊瘉杩欎竴鐐癸紝鍦ㄩ摼鎺ユ垨鍔ㄦ佽澆鍏ュ姩鎬佸簱鏃訛紝灝變細(xì)鍑虹幇蹇界暐閲嶅絎﹀彿鐨勬儏鍐點(diǎn)?/p> <p><em>榪欓噷灝變笉鎻愬悓涓涓摼鎺ュ崟浣嶏紙濡傚彲鎵ц紼嬪簭銆佸姩鎬佸簱錛夐噷絎﹀彿閲嶅鐨勯棶棰樹(shù)簡(jiǎn)</em></p> <h3>鍑芥暟</h3> <p>褰撳姩鎬佸簱鍜宭ibdy.so鍙墽琛岀▼搴弔est涓寘鍚悓鍚嶇殑鍑芥暟鏃朵細(xì)鎬庢牱錛熸牴鎹槸鍚﹀姩鎬佸姞杞芥儏鍐佃繕鏈夋墍涓嶅悓銆?/p> <p>褰撶洿鎺ラ摼鎺ュ姩鎬佸簱鏃訛紝libdy.so鍜宼est閮戒細(xì)閾炬帴鍖呭惈<code>func</code>鍑芥暟鐨刦un.o錛屼負(fù)浜?jiǎn)鍖哄垎锛屾垜鎶?code>func</code>鎸夌収鏉′歡緙栬瘧寰楀埌涓嶅悓鐨勭増鏈細(xì)</p> <div id="hvzpftn" class="highlight"><pre><code class="language-c--" data-lang="c++"><span id="hvzpftn" class="c1">// fun.cpp</span> <span id="hvzpftn" class="cp">#ifdef V2</span> <span id="hvzpftn" class="k">extern</span> <span id="hvzpftn" class="s">"C"</span> <span id="hvzpftn" class="kt">void</span> <span id="hvzpftn" class="n">func</span><span id="hvzpftn" class="p">()</span> <span id="hvzpftn" class="p">{</span> <span id="hvzpftn" class="n">printf</span><span id="hvzpftn" class="p">(</span><span id="hvzpftn" class="s">"func v2</span><span id="hvzpftn" class="se">\n</span><span id="hvzpftn" class="s">"</span><span id="hvzpftn" class="p">);</span> <span id="hvzpftn" class="p">}</span> <span id="hvzpftn" class="cp">#else</span> <span id="hvzpftn" class="k">extern</span> <span id="hvzpftn" class="s">"C"</span> <span id="hvzpftn" class="kt">void</span> <span id="hvzpftn" class="n">func</span><span id="hvzpftn" class="p">()</span> <span id="hvzpftn" class="p">{</span> <span id="hvzpftn" class="n">printf</span><span id="hvzpftn" class="p">(</span><span id="hvzpftn" class="s">"func v1</span><span id="hvzpftn" class="se">\n</span><span id="hvzpftn" class="s">"</span><span id="hvzpftn" class="p">);</span> <span id="hvzpftn" class="p">}</span> <span id="hvzpftn" class="cp">#endif</span> <span id="hvzpftn" class="c1">// Makefile</span> <span id="hvzpftn" class="nl">test</span><span id="hvzpftn" class="p">:</span> <span id="hvzpftn" class="n">libdy</span> <span id="hvzpftn" class="n">obj</span><span id="hvzpftn" class="p">.</span><span id="hvzpftn" class="n">o</span> <span id="hvzpftn" class="n">mainfn</span> <span id="hvzpftn" class="n">g</span><span id="hvzpftn" class="o">++</span> <span id="hvzpftn" class="o">-</span><span id="hvzpftn" class="n">g</span> <span id="hvzpftn" class="o">-</span><span id="hvzpftn" class="n">Wall</span> <span id="hvzpftn" class="o">-</span><span id="hvzpftn" class="n">c</span> <span id="hvzpftn" class="n">fun</span><span id="hvzpftn" class="p">.</span><span id="hvzpftn" class="n">cpp</span> <span id="hvzpftn" class="o">-</span><span id="hvzpftn" class="n">o</span> <span id="hvzpftn" class="n">fun</span><span id="hvzpftn" class="p">.</span><span id="hvzpftn" class="n">o</span> <span id="hvzpftn" class="err">#</span> <span id="hvzpftn" class="err">緙栬瘧涓?/span><span id="hvzpftn" class="n">fun</span><span id="hvzpftn" class="p">.</span><span id="hvzpftn" class="n">o</span> <span id="hvzpftn" class="n">g</span><span id="hvzpftn" class="o">++</span> <span id="hvzpftn" class="o">-</span><span id="hvzpftn" class="n">g</span> <span id="hvzpftn" class="o">-</span><span id="hvzpftn" class="n">Wall</span> <span id="hvzpftn" class="o">-</span><span id="hvzpftn" class="n">c</span> <span id="hvzpftn" class="n">main</span><span id="hvzpftn" class="p">.</span><span id="hvzpftn" class="n">cpp</span> <span id="hvzpftn" class="err">#</span><span id="hvzpftn" class="o">-</span><span id="hvzpftn" class="n">DDY_LOAD</span> <span id="hvzpftn" class="n">g</span><span id="hvzpftn" class="o">++</span> <span id="hvzpftn" class="o">-</span><span id="hvzpftn" class="n">g</span> <span id="hvzpftn" class="o">-</span><span id="hvzpftn" class="n">Wall</span> <span id="hvzpftn" class="o">-</span><span id="hvzpftn" class="n">o</span> <span id="hvzpftn" class="n">test</span> <span id="hvzpftn" class="n">main</span><span id="hvzpftn" class="p">.</span><span id="hvzpftn" class="n">o</span> <span id="hvzpftn" class="n">obj</span><span id="hvzpftn" class="p">.</span><span id="hvzpftn" class="n">o</span> <span id="hvzpftn" class="n">fun</span><span id="hvzpftn" class="p">.</span><span id="hvzpftn" class="n">o</span> <span id="hvzpftn" class="o">-</span><span id="hvzpftn" class="n">ldl</span> <span id="hvzpftn" class="n">mfun</span><span id="hvzpftn" class="p">.</span><span id="hvzpftn" class="n">o</span> <span id="hvzpftn" class="o">-</span><span id="hvzpftn" class="n">ldy</span> <span id="hvzpftn" class="o">-</span><span id="hvzpftn" class="n">L</span><span id="hvzpftn" class="p">.</span> <span id="hvzpftn" class="nl">libdy</span><span id="hvzpftn" class="p">:</span> <span id="hvzpftn" class="n">obj</span> <span id="hvzpftn" class="n">g</span><span id="hvzpftn" class="o">++</span> <span id="hvzpftn" class="o">-</span><span id="hvzpftn" class="n">Wall</span> <span id="hvzpftn" class="o">-</span><span id="hvzpftn" class="n">fPIC</span> <span id="hvzpftn" class="o">-</span><span id="hvzpftn" class="n">c</span> <span id="hvzpftn" class="n">fun</span><span id="hvzpftn" class="p">.</span><span id="hvzpftn" class="n">cpp</span> <span id="hvzpftn" class="o">-</span><span id="hvzpftn" class="n">DV2</span> <span id="hvzpftn" class="o">-</span><span id="hvzpftn" class="n">o</span> <span id="hvzpftn" class="n">fun</span><span id="hvzpftn" class="o">-</span><span id="hvzpftn" class="n">dy</span><span id="hvzpftn" class="p">.</span><span id="hvzpftn" class="n">o</span> <span id="hvzpftn" class="err">#</span> <span id="hvzpftn" class="err">瀹氫箟</span><span id="hvzpftn" class="n">V2</span><span id="hvzpftn" class="err">瀹忥紝緙栬瘧涓?/span><span id="hvzpftn" class="n">fun</span><span id="hvzpftn" class="o">-</span><span id="hvzpftn" class="n">dy</span><span id="hvzpftn" class="p">.</span><span id="hvzpftn" class="n">o</span> <span id="hvzpftn" class="n">g</span><span id="hvzpftn" class="o">++</span> <span id="hvzpftn" class="o">-</span><span id="hvzpftn" class="n">Wall</span> <span id="hvzpftn" class="o">-</span><span id="hvzpftn" class="n">fPIC</span> <span id="hvzpftn" class="o">-</span><span id="hvzpftn" class="n">shared</span> <span id="hvzpftn" class="o">-</span><span id="hvzpftn" class="n">o</span> <span id="hvzpftn" class="n">libdy</span><span id="hvzpftn" class="p">.</span><span id="hvzpftn" class="n">so</span> <span id="hvzpftn" class="n">dy</span><span id="hvzpftn" class="p">.</span><span id="hvzpftn" class="n">cpp</span> <span id="hvzpftn" class="o">-</span><span id="hvzpftn" class="n">g</span> <span id="hvzpftn" class="n">obj</span><span id="hvzpftn" class="p">.</span><span id="hvzpftn" class="n">o</span> <span id="hvzpftn" class="n">fun</span><span id="hvzpftn" class="o">-</span><span id="hvzpftn" class="n">dy</span><span id="hvzpftn" class="p">.</span><span id="hvzpftn" class="n">o</span></code></pre></div> <p>榪欐牱錛宼est涓殑<code>func</code>灝變細(xì)杈撳嚭<code>func v1</code>錛沴ibdy.so涓殑<code>func</code>灝變細(xì)杈撳嚭<code>func v2</code>銆倀est鍜宭ibdy.o紜疄閮芥湁<code>func</code>絎﹀彿錛?/p> <pre><code>$ nm libdy.so | grep func 0000000000000a60 T func $nm test | grep func 0000000000400a80 T func </code></pre> <p>鍦╰est鍜宭ibdy.so涓兘浼?xì)璋冪?code>func</code>鍑芥暟錛?/p> <div id="hvzpftn" class="highlight"><pre><code class="language-c--" data-lang="c++"><span id="hvzpftn" class="c1">// main.cpp test</span> <span id="hvzpftn" class="kt">int</span> <span id="hvzpftn" class="nf">main</span><span id="hvzpftn" class="p">(</span><span id="hvzpftn" class="kt">int</span> <span id="hvzpftn" class="n">argc</span><span id="hvzpftn" class="p">,</span> <span id="hvzpftn" class="kt">char</span> <span id="hvzpftn" class="o">**</span><span id="hvzpftn" class="n">argv</span><span id="hvzpftn" class="p">)</span> <span id="hvzpftn" class="p">{</span> <span id="hvzpftn" class="n">func</span><span id="hvzpftn" class="p">();</span> <span id="hvzpftn" class="p">...</span> <span id="hvzpftn" class="n">callfn</span><span id="hvzpftn" class="p">();</span> <span id="hvzpftn" class="c1">// 璋冪敤libdy.so涓殑鍑芥暟</span> <span id="hvzpftn" class="p">...</span> <span id="hvzpftn" class="p">}</span> <span id="hvzpftn" class="c1">// dy.cpp libdy.so</span> <span id="hvzpftn" class="k">extern</span> <span id="hvzpftn" class="s">"C"</span> <span id="hvzpftn" class="kt">void</span> <span id="hvzpftn" class="n">callfn</span><span id="hvzpftn" class="p">()</span> <span id="hvzpftn" class="p">{</span> <span id="hvzpftn" class="p">...</span> <span id="hvzpftn" class="n">printf</span><span id="hvzpftn" class="p">(</span><span id="hvzpftn" class="s">"callfn</span><span id="hvzpftn" class="se">\n</span><span id="hvzpftn" class="s">"</span><span id="hvzpftn" class="p">);</span> <span id="hvzpftn" class="n">func</span><span id="hvzpftn" class="p">();</span> <span id="hvzpftn" class="p">...</span> <span id="hvzpftn" class="p">}</span></code></pre></div> <p>榪愯鍚庡彂鐜幫紝閮?strong>璋冪敤鐨勬槸鍚屼竴涓?code>func</code></strong>錛?/p> <pre><code>$ ./test ... func v1 ... callfn func v1 </code></pre> <p><strong>緇撹</strong>錛岀洿鎺ラ摼鎺ュ姩鎬佸簱鏃訛紝鏁翠釜紼嬪簭榪愯鐨勬椂鍊欑鍙蜂細(xì)鍙戠敓瑕嗙洊錛屽彧鏈変竴涓鍙瘋浣跨敤銆?strong>鍦ㄥ疄璺典腑</strong>錛屽鏋滅▼搴忓拰閾炬帴鐨勫姩鎬佸簱閮戒緷璧栦簡(jiǎn)涓涓潤(rùn)鎬佸簱錛岃屽悗浠栦滑閾炬帴鐨勮繖涓潤(rùn)鎬佸簱鐗堟湰涓嶅悓錛屽垯寰堟湁鍙兘鍥犱負(fù)絎﹀彿鍙戠敓浜?jiǎn)瑕嗙洊鑰屽鑷撮棶棰樸?闈?rùn)鎬佸簱鍚屾櫘閫氱殑.o鎬ц川涓鏍鳳紝鍙傝?a >嫻呮瀽闈?rùn)鎬佸簱閾炬帴鍘熺悊</a>)</p> <p>鏇村鏉傜殑鎯呭喌涓紝澶氫釜鍔ㄦ佸簱鍜岀▼搴忛兘鏈夌浉鍚岀殑絎﹀彿錛屾儏鍐典篃鏄竴鏍鳳紝浼?xì)鍙戠敓绗﹀彲偊嗙洊銆傚鏋滅▼搴忛噷娌℃湁榪欎釜絎﹀彿錛岃屽涓姩鎬佸簱閲屾湁鐩稿悓鐨勭鍙鳳紝涔熶細(xì)瑕嗙洊銆?/p> <p>浣嗘槸瀵逛簬鍔ㄦ佽澆鍏ョ殑鎯呭喌鍒欎笉鍚岋紝鍚屾牱鐨刲ibdy.so鎴戜滑鍦╰est涓笉閾炬帴錛岃屾槸鍔ㄦ佽澆鍏ワ細(xì)</p> <div id="hvzpftn" class="highlight"><pre><code class="language-c--" data-lang="c++"><span id="hvzpftn" class="kt">int</span> <span id="hvzpftn" class="nf">main</span><span id="hvzpftn" class="p">(</span><span id="hvzpftn" class="kt">int</span> <span id="hvzpftn" class="n">argc</span><span id="hvzpftn" class="p">,</span> <span id="hvzpftn" class="kt">char</span> <span id="hvzpftn" class="o">**</span><span id="hvzpftn" class="n">argv</span><span id="hvzpftn" class="p">)</span> <span id="hvzpftn" class="p">{</span> <span id="hvzpftn" class="n">func</span><span id="hvzpftn" class="p">();</span> <span id="hvzpftn" class="cp">#ifdef DY_LOAD</span> <span id="hvzpftn" class="kt">void</span> <span id="hvzpftn" class="o">*</span><span id="hvzpftn" class="n">dp</span> <span id="hvzpftn" class="o">=</span> <span id="hvzpftn" class="n">dlopen</span><span id="hvzpftn" class="p">(</span><span id="hvzpftn" class="s">"./libdy.so"</span><span id="hvzpftn" class="p">,</span> <span id="hvzpftn" class="n">RTLD_LAZY</span><span id="hvzpftn" class="p">);</span> <span id="hvzpftn" class="k">typedef</span> <span id="hvzpftn" class="kt">void</span> <span id="hvzpftn" class="p">(</span><span id="hvzpftn" class="o">*</span><span id="hvzpftn" class="n">callfn</span><span id="hvzpftn" class="p">)();</span> <span id="hvzpftn" class="n">callfn</span> <span id="hvzpftn" class="n">f</span> <span id="hvzpftn" class="o">=</span> <span id="hvzpftn" class="p">(</span><span id="hvzpftn" class="n">callfn</span><span id="hvzpftn" class="p">)</span> <span id="hvzpftn" class="n">dlsym</span><span id="hvzpftn" class="p">(</span><span id="hvzpftn" class="n">dp</span><span id="hvzpftn" class="p">,</span> <span id="hvzpftn" class="s">"callfn"</span><span id="hvzpftn" class="p">);</span> <span id="hvzpftn" class="n">f</span><span id="hvzpftn" class="p">();</span> <span id="hvzpftn" class="n">func</span><span id="hvzpftn" class="p">();</span> <span id="hvzpftn" class="n">dlclose</span><span id="hvzpftn" class="p">(</span><span id="hvzpftn" class="n">dp</span><span id="hvzpftn" class="p">);</span> <span id="hvzpftn" class="cp">#else</span> <span id="hvzpftn" class="n">callfn</span><span id="hvzpftn" class="p">();</span> <span id="hvzpftn" class="cp">#endif</span> <span id="hvzpftn" class="k">return</span> <span id="hvzpftn" class="mi">0</span><span id="hvzpftn" class="p">;</span> <span id="hvzpftn" class="p">}</span></code></pre></div> <p>榪愯寰楀埌錛?/p> <pre><code>$ ./test func v1 ... callfn func v2 func v1 </code></pre> <p>閮芥紜湴璋冪敤鍒板悇鑷摼鎺ョ殑<code>func</code>銆?/p> <p><strong>緇撹</strong>錛屽疄璺典腑錛屽姩鎬佽澆鍏ョ殑鍔ㄦ佸簱涓鑸細(xì)浣滀負(fù)鎻掍歡浣跨敤錛岄偅涔堝叾鍚岀▼搴忛摼鎺ヤ笉鍚岀増鏈殑闈?rùn)鎬佸簱錛堢浉鍚岀鍙蜂笉鍚屽疄鐜幫級(jí)錛屾槸娌℃湁闂鐨勩?/p> <h3>鍙橀噺</h3> <p>鍙橀噺鏈川涓婁篃鏄鍙?symbol)錛屼絾鍏跺鐞嗚鍒欏拰鍑芥暟榪樻湁鐐逛笉涓鏍?<em>鏄笉鏄湁鐐規(guī)兂鍚愭Ы浜?/em>)銆?/p> <div id="hvzpftn" class="highlight"><pre><code class="language-c--" data-lang="c++"><span id="hvzpftn" class="c1">// object.h</span> <span id="hvzpftn" class="k">class</span> <span id="hvzpftn" class="nc">Object</span> <span id="hvzpftn" class="p">{</span> <span id="hvzpftn" class="k">public</span><span id="hvzpftn" class="o">:</span> <span id="hvzpftn" class="n">Object</span><span id="hvzpftn" class="p">()</span> <span id="hvzpftn" class="p">{</span> <span id="hvzpftn" class="cp">#ifdef DF</span> <span id="hvzpftn" class="n">s</span> <span id="hvzpftn" class="o">=</span> <span id="hvzpftn" class="n">malloc</span><span id="hvzpftn" class="p">(</span><span id="hvzpftn" class="mi">32</span><span id="hvzpftn" class="p">);</span> <span id="hvzpftn" class="n">printf</span><span id="hvzpftn" class="p">(</span><span id="hvzpftn" class="s">"s addr %p</span><span id="hvzpftn" class="se">\n</span><span id="hvzpftn" class="s">"</span><span id="hvzpftn" class="p">,</span> <span id="hvzpftn" class="n">s</span><span id="hvzpftn" class="p">);</span> <span id="hvzpftn" class="cp">#endif</span> <span id="hvzpftn" class="n">printf</span><span id="hvzpftn" class="p">(</span><span id="hvzpftn" class="s">"ctor %p</span><span id="hvzpftn" class="se">\n</span><span id="hvzpftn" class="s">"</span><span id="hvzpftn" class="p">,</span> <span id="hvzpftn" class="k">this</span><span id="hvzpftn" class="p">);</span> <span id="hvzpftn" class="p">}</span> <span id="hvzpftn" class="o">~</span><span id="hvzpftn" class="n">Object</span><span id="hvzpftn" class="p">()</span> <span id="hvzpftn" class="p">{</span> <span id="hvzpftn" class="n">printf</span><span id="hvzpftn" class="p">(</span><span id="hvzpftn" class="s">"dtor %p</span><span id="hvzpftn" class="se">\n</span><span id="hvzpftn" class="s">"</span><span id="hvzpftn" class="p">,</span> <span id="hvzpftn" class="k">this</span><span id="hvzpftn" class="p">);</span> <span id="hvzpftn" class="cp">#ifdef DF</span> <span id="hvzpftn" class="n">printf</span><span id="hvzpftn" class="p">(</span><span id="hvzpftn" class="s">"s addr %p</span><span id="hvzpftn" class="se">\n</span><span id="hvzpftn" class="s">"</span><span id="hvzpftn" class="p">,</span> <span id="hvzpftn" class="n">s</span><span id="hvzpftn" class="p">);</span> <span id="hvzpftn" class="n">free</span><span id="hvzpftn" class="p">(</span><span id="hvzpftn" class="n">s</span><span id="hvzpftn" class="p">);</span> <span id="hvzpftn" class="cp">#endif</span> <span id="hvzpftn" class="p">}</span> <span id="hvzpftn" class="kt">void</span> <span id="hvzpftn" class="o">*</span><span id="hvzpftn" class="n">s</span><span id="hvzpftn" class="p">;</span> <span id="hvzpftn" class="p">};</span> <span id="hvzpftn" class="k">extern</span> <span id="hvzpftn" class="n">Object</span> <span id="hvzpftn" class="n">g_obj</span><span id="hvzpftn" class="p">;</span></code></pre></div> <p>鎴戜滑鐨勭▼搴弔est鍜屽姩鎬佸簱libdy.so閮戒細(xì)閾炬帴object.o銆傞鍏堟祴璇晅est閾炬帴libdy.so錛宼est鍜宭ibdy.so涓兘浼?xì)鏈?code>g_obj</code>榪欎釜絎﹀彿錛?/p> <pre><code>// B g_obj 琛ㄧずg_obj浣嶄簬BSS孌碉紝鏈垵濮嬪寲孌? $ nm test | grep g_obj 0000000000400a14 t _GLOBAL__I_g_obj 00000000006012c8 B g_obj $ nm libdy.so | grep g_obj 000000000000097c t _GLOBAL__I_g_obj 0000000000200f30 B g_obj </code></pre> <p>榪愯錛?/p> <pre><code>$ ./test ctor 0x6012c8 ctor 0x6012c8 ... dtor 0x6012c8 dtor 0x6012c8 </code></pre> <p><strong><code>g_obj</code>琚瀯閫犱簡(jiǎn)涓ゆ錛屼絾鍦板潃涓鏍?/strong>銆傚叏灞鍙橀噺鍙湁涓涓疄渚嬶紝浼間箮鍦ㄦ儏鐞嗕箣涓?/p> <p>鍔ㄦ佽澆鍏ibdy.so錛屽彉閲忓湴鍧榪樻槸鐩稿悓鐨勶細(xì)</p> <pre><code>$ ./test ctor 0x6012a8 ... ctor 0x6012a8 ... dtor 0x6012a8 dtor 0x6012a8 </code></pre> <p><strong>緇撹</strong>錛屼笉鍚屼簬鍑芥暟錛屽叏灞鍙橀噺絎﹀彿閲嶅鏃訛紝涓嶈鍔ㄦ佸簱鏄姩鎬佽澆鍏ヨ繕鏄洿鎺ラ摼鎺ワ紝鍙橀噺濮嬬粓鍙湁涓涓?/p> <p>浣嗚寮傜殑鎯呭喌鏄紝瀵硅薄琚瀯閫犲拰鏋愭瀯浜?jiǎn)涓啤銆傛瀯閫犱袱嬈″掓棤鎵璋擄紝嫻垂鐐圭┖闂達(dá)紝浣嗘槸鏋愭瀯涓ゆ灝辨湁闂銆傚洜涓烘瀽鏋勬椂閮芥搷浣滅殑鏄悓涓涓璞★紝閭d箞濡傛灉榪欎釜瀵硅薄鍐呴儴鏈夊垎閰嶇殑鍐呭瓨錛岄偅灝變細(xì)瀵硅繖鍧楀唴瀛橀犳垚double free錛屽洜涓烘寚閽堢浉鍚屻傛墦寮<code>DF</code>瀹忓疄楠屼笅錛?/p> <pre><code>$ ./test s addr 0x20de010 ctor 0x6012b8 s addr 0x20de040 ctor 0x6012b8 ... dtor 0x6012b8 s addr 0x20de040 dtor 0x6012b8 s addr 0x20de040 </code></pre> <p>鍥犱負(fù)鏋愭瀯鐨勪袱嬈¢兘鏄悓涓涓璞★紝鎵浠ュ叾鎴愬憳<code>s</code>鎸囧悜鐨勫唴瀛樿閲婃斁浜?jiǎn)涓啤锛屼粠鑰屼駭鐢熶簡(jiǎn)double free錛岃紼嬪簭coredump浜?jiǎn)銆?/p> <p><strong>鎬葷粨</strong>錛屽叏灞鍙橀噺絎﹀彿閲嶅鏃訛紝濮嬬粓浼?xì)鍙娇鐢ㄤ竴涓紝騫朵笖浼?xì)琚垵濮嬪?閲婃斁涓ゆ錛屾槸涓縐嶈緝鍗遍櫓鐨勬儏鍐碉紝搴斿綋閬垮厤鍦ㄤ嬌鐢ㄥ姩鎬佸簱鐨勮繃紼嬩腑浣跨敤鍏ㄥ眬鍙橀噺銆?/p> <p><em>瀹?/em></p> <p class="post-footer"> 鍘熸枃鍦板潃錛? <a >http://codemacro.com/2014/11/04/linux-dynamic-library/</a><br /> written by <a >Kevin Lynx</a>  posted at <a >http://codemacro.com</a> </p> </div><img src ="http://m.shnenglu.com/kevinlynx/aggbug/208761.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://m.shnenglu.com/kevinlynx/" target="_blank">Kevin Lynx</a> 2014-11-04 00:55 <a href="http://m.shnenglu.com/kevinlynx/archive/2014/11/04/208761.html#Feedback" target="_blank" style="text-decoration:none;">鍙戣〃璇勮</a></div>]]></description></item><item><title>鍥捐Вzookeeper FastLeader閫変婦綆楁硶http://m.shnenglu.com/kevinlynx/archive/2014/10/19/208622.htmlKevin LynxKevin LynxSun, 19 Oct 2014 07:58:00 GMThttp://m.shnenglu.com/kevinlynx/archive/2014/10/19/208622.htmlhttp://m.shnenglu.com/kevinlynx/comments/208622.htmlhttp://m.shnenglu.com/kevinlynx/archive/2014/10/19/208622.html#Feedback0http://m.shnenglu.com/kevinlynx/comments/commentRss/208622.htmlhttp://m.shnenglu.com/kevinlynx/services/trackbacks/208622.html

zookeeper閰嶇疆涓洪泦緹ゆā寮忔椂錛屽湪鍚姩鎴栧紓甯告儏鍐墊椂浼?xì)閫変婦鍑轟竴涓疄渚嬩綔涓篖eader銆傚叾榛樿閫変婦綆楁硶涓?code>FastLeaderElection銆?/p>

涓嶇煡閬搝ookeeper鐨勫彲浠ヨ冭檻榪欐牱涓涓棶棰橈細(xì)鏌愪釜鏈嶅姟鍙互閰嶇疆涓哄涓疄渚嬪叡鍚屾瀯鎴愪竴涓泦緹ゅ澶栨彁渚涙湇鍔°傚叾姣忎竴涓疄渚嬫湰鍦伴兘瀛樻湁鍐椾綑鏁版嵁錛屾瘡涓涓疄渚嬮兘鍙互鐩存帴瀵瑰鎻愪緵璇誨啓鏈嶅姟銆傚湪榪欎釜闆嗙兢涓負(fù)浜?jiǎn)淇濊瘉鏁版嵁鐨勪竴鑷存э紝闇瑕佹湁涓涓狶eader鏉ュ崗璋冧竴浜涗簨鍔°傞偅涔堥棶棰樻潵浜?jiǎn)锛?xì)濡備綍紜畾鍝竴涓疄渚嬫槸Leader鍛紵

闂鐨勯毦鐐瑰湪浜庯細(xì)

  • 娌℃湁涓涓徊瑁佽呮潵閫夊畾Leader
  • 姣忎竴涓疄渚嬫湰鍦板彲鑳藉凡緇忓瓨鍦ㄦ暟鎹紝涓嶇‘瀹氬摢涓疄渚嬩笂鐨勬暟鎹槸鏈鏂扮殑

鍒嗗竷寮忛変婦綆楁硶姝f槸鐢ㄦ潵瑙e喅榪欎釜闂鐨勩?/p>

鏈枃鍩轟簬zookeeper 3.4.6 鐨勬簮鐮佽繘琛屽垎鏋愩侳astLeaderElection綆楁硶鐨勬簮鐮佸叏閮ㄤ綅浜?code>FastLeaderElection.java鏂囦歡涓紝鍏跺澶栨帴鍙d負(fù)FastLeaderElection.lookForLeader錛岃鎺ュ彛鏄竴涓悓姝ユ帴鍙o紝鐩村埌閫変婦緇撴潫鎵嶄細(xì)榪斿洖銆傚悓鏍風(fēng)敱浜庣綉涓婂凡鏈夌被浼兼枃绔狅紝鎵浠ユ垜灝變粠鍥劇ず鐨勮搴︽潵闃愯堪銆傞槄璇諱竴浜涘叾浠栨枃绔犳湁鍒╀簬鑾峰緱鍒濇鍗拌薄錛?/p>

涓昏嫻佺▼

闃呰浠g爜鍜屼互涓婃帹鑽愭枃绔犲彲浠ユ妸鏁翠釜嫻佺▼姊崇悊娓呮銆傚疄鐜頒笂錛屽寘鎷簡(jiǎn)涓涓秷鎭鐞嗕富寰幆錛屼篃鏄変婦鐨勪富瑕侀昏緫錛屼互鍙?qiáng)涓涓秷鎭彂閫侀槦鍒楀鐞嗙嚎紼嬪拰娑堟伅瑙g爜綰跨▼銆備富瑕佹祦紼嬪彲姒傛嫭涓轟笅鍥撅細(xì)

fle-flow.png

鎺ㄨ崘瀵圭収鐫鎺ㄨ崘鐨勬枃绔犲強(qiáng)浠g爜鐞嗚В錛屼笉璧樿堪銆?/p>

鎴戜滑浠庢劅鎬т笂鏉ョ悊瑙h繖涓畻娉曘?/p>

姣忎竴涓妭鐐癸紝鐩稿綋浜庝竴涓夋皯錛屼粬浠兘鏈夎嚜宸辯殑鎺ㄨ崘浜猴紝鏈寮濮嬩粬浠兘鎺ㄨ崘鑷繁銆傝皝鏇撮傚悎鎴愪負(fù)Leader鏈変竴涓畝鍗曠殑瑙勫垯錛屼緥濡俿id澶熷ぇ錛堥厤緗級(jí)銆佹寔鏈夌殑鏁版嵁澶熸柊(zxid澶熷ぇ)銆傛瘡涓夋皯閮藉憡璇夊叾浠栭夋皯鑷繁鐩墠鐨勬帹鑽愪漢鏄皝錛岀被浼間簬鍑哄幓鎼炲浼犳媺鎷㈠叾浠栭夋皯銆傛瘡涓涓夋皯鍙戠幇鏈夋瘮鑷繁鏇撮傚悎鐨勪漢鏃跺氨杞屾帹鑽愯繖涓洿閫傚悎鐨勪漢銆傛渶鍚庯紝澶ч儴鍒嗕漢鎰忚涓鑷存椂錛屽氨鍙互緇撴潫閫変婦銆?/p>

灝辮繖涔堢畝鍗曘傛諱綋涓婃湁涓縐嶄笉鏂紨鍖栭艱繎緇撴灉鐨勬劅瑙夈?/p>

褰撶劧錛屼細(xì)鏈変簺鐗規(guī)畩鎯呭喌鐨勫鐞嗐備緥濡傛誨叡3涓夋皯錛?鍜?宸茬粡紜畾3鏄疞eader錛屼絾3榪樹(shù)笉鐭ユ儏錛屾鏃跺氨璧板叆LEADING/FOLLOWING鐨勫垎鏀紝閫夋皯3鍙槸鎺ユ敹緇撴灉銆?/p>

浠g爜涓笉鏄墍鏈夐昏緫閮藉湪榪欎釜澶ф祦紼嬩腑瀹屾垚鐨勩傚湪鎺ユ敹娑堟伅綰跨▼涓紝榪樺彲鑳藉崟鐙湴鍥炲簲鏌愪釜鑺傜偣(WorkerReceiver.run)錛?/p>

recv.png

浠庤繖閲屽彲浠ョ湅鍑猴紝褰撴煇涓妭鐐瑰凡緇忕‘瀹氶変婦緇撴灉涓嶅啀澶勪簬LOOKING鐘舵佹椂錛屽叾鏀跺埌LOOKING娑堟伅鏃墮兘浼?xì)鐩存帴鍥炲簲閫変婦鐨勬渶緇堢粨鏋溿傜粨鍚堜笂闈㈤偅涓瘮鏂癸紝鐩稿綋浜庢煇嬈¢変婦緇撴潫浜?jiǎn)锛寴q欎釜鏃跺欐潵浜?jiǎn)閫夋皯4鍙堝彂璧蜂竴嬈℃柊鐨勯変婦錛岄偅涔堝叾浠栭夋皯灝辯洿鎺ュ憡璇夊畠褰撳墠鐨凩eader鎯呭喌銆傜浉褰撲簬錛屽湪榪欎釜闆嗙兢涓諱粠宸茬粡灝辯華鐨勬儏鍐典笅錛屽張寮鍚簡(jiǎn)涓涓疄渚嬶紝榪欎釜瀹炰緥灝變細(xì)鐩存帴浣跨敤褰撳墠鐨勯変婦緇撴灉銆?/p>

鐘舵佽漿鎹?/h2>

姣忎釜鑺傜偣涓婃湁涓浜涘叧閿殑鏁版嵁緇撴瀯錛?/p>

  • 褰撳墠鎺ㄨ崘浜猴紝鍒濆鎺ㄨ崘鑷繁錛屾瘡嬈℃敹鍒板叾浠栨洿濂界殑鎺ㄨ崘浜烘椂灝辨洿鏂?/li>
  • 鍏朵粬浜虹殑鎶曠エ闆嗗悎錛岀敤浜庣‘瀹氫綍鏃墮変婦緇撴潫

姣忔鎺ㄨ崘浜烘洿鏂版椂灝變細(xì)榪涜騫挎挱錛屾鏄繖涓笉鏂湴騫挎挱椹卞姩鏁翠釜綆楁硶瓚嬪悜浜庣粨鏋溿傚亣璁炬湁3涓妭鐐笰/B/C錛屽叾閮借繕娌℃湁鏁版嵁錛屾寜鐓id鍏崇郴涓篊>B>A錛岄偅涔堟寜鐓ц鍒欙紝C鏇村彲鑳芥垚涓篖eader錛屽叾鍚勪釜鑺傜偣鐨勭姸鎬佽漿鎹負(fù)錛?/p>

state.png

鍥句腑錛寁(A)琛ㄧず褰撳墠鎺ㄨ崘浜轟負(fù)A錛況[]琛ㄧず鏀跺埌鐨勬姇紲ㄩ泦鍚堛?/p>

鍙互鐪嬬湅褰撳叾浠栬妭鐐瑰凡緇忕‘瀹氭姇紲ㄧ粨鏋滄椂錛屽嵆涓嶅啀鏄?code>LOOKING鏃剁殑鐘舵侊細(xì)

state-ret.png

浠g爜涓湁涓涓壒孌婄殑鎶曠エ闆嗗悎outofelection錛屾垜鐞嗚В涓洪変婦宸茬粨鏉熺殑閭d簺鎶曠エ錛岃繖浜涙姇紲ㄤ粎鐢ㄤ簬琛ㄥ緛閫変婦緇撴灉銆?/p>

褰撲竴涓柊鍚姩鐨勮妭鐐瑰姞鍏ラ泦緹ゆ椂錛屽畠瀵歸泦緹ゅ唴鍏朵粬鑺傜偣鍙戝嚭鎶曠エ璇鋒眰錛岃屽叾浠栬妭鐐瑰凡涓嶅浜?code>LOOKING鐘舵侊紝姝ゆ椂鍏朵粬鑺傜偣鍥炲簲閫変婦緇撴灉錛岃鑺傜偣鏀墮泦榪欎簺緇撴灉鍒?code>outofelection涓紝鏈緇堝湪鏀跺埌鍚堟硶LEADER娑堟伅涓旇繖浜涢夌エ涔熸瀯鎴愰変婦緇撴潫鏉′歡鏃訛紝璇ヨ妭鐐瑰氨緇撴潫鑷繁鐨勯変婦琛屼負(fù)銆?em>娉ㄦ剰鍒頒唬鐮佷腑浼?code>logicalclock = n.electionEpoch;鏇存柊閫変婦杞暟

瀹?/em>



]]>鍥捐В鍒嗗竷寮忎竴鑷存у崗璁甈axoshttp://m.shnenglu.com/kevinlynx/archive/2014/10/15/208580.htmlKevin LynxKevin LynxWed, 15 Oct 2014 14:45:00 GMThttp://m.shnenglu.com/kevinlynx/archive/2014/10/15/208580.htmlhttp://m.shnenglu.com/kevinlynx/comments/208580.htmlhttp://m.shnenglu.com/kevinlynx/archive/2014/10/15/208580.html#Feedback6http://m.shnenglu.com/kevinlynx/comments/commentRss/208580.htmlhttp://m.shnenglu.com/kevinlynx/services/trackbacks/208580.html

Paxos鍗忚/綆楁硶鏄垎甯冨紡緋葷粺涓瘮杈冮噸瑕佺殑鍗忚錛屽畠鏈夊閲嶈鍛紵

<鍒嗗竷寮忕郴緇熺殑浜嬪姟澶勭悊>錛?/p>

Google Chubby鐨勪綔鑰匨ike Burrows璇磋繃榪欎釜涓栫晫涓婂彧鏈変竴縐嶄竴鑷存х畻娉曪紝閭e氨鏄疨axos錛屽叾瀹冪殑綆楁硶閮芥槸孌嬫鍝併?/p>

<澶ц妯″垎甯冨紡瀛樺偍緋葷粺>錛?/p>

鐞嗚В浜?jiǎn)杩欎袱涓垎甯冨紡鍗忚涔嬪?Paxos/2PC)錛屽涔?fàn)鍏朵粬鍒嗗竷寮忓崗璁細(xì)鍙樺緱鐩稿綋瀹规槗銆?/p>

瀛︿範(fàn)Paxos綆楁硶鏈変袱閮ㄥ垎錛歛) 綆楁硶鐨勫師鐞?璇佹槑錛沚) 綆楁硶鐨勭悊瑙?榪愪綔銆?/p>

鐞嗚В榪欎釜綆楁硶鐨勮繍浣滆繃紼嬪叾瀹炲熀鏈氨鍙互鐢ㄤ簬宸ョ▼瀹炶返銆傝屼笖鐞嗚В榪欎釜榪囩▼鐩稿鏉ヨ涔熷鏄撳緱澶氥?/p>

緗戜笂鎴戣寰楄Paxos璁茬殑濂界殑灞炰簬榪欑瘒錛?a >paxos鍥捐В鍙?a >Paxos綆楁硶璇﹁В錛屾垜榪欓噷灝辯粨鍚?a >wiki涓婄殑瀹炰緥榪涗竴姝ラ槓榪般備竴浜沺axos鍩虹閫氳繃榪欓噷鎻愬埌鐨勪袱綃囨枃绔狅紝浠ュ強(qiáng)wiki涓婄殑鍐呭鍩烘湰鍙互鐞嗚В銆?/p>

綆楁硶鍐呭

Paxos鍦ㄥ師浣滆呯殑銆奝axos Made Simple銆嬩腑鍐呭鏄瘮杈冪簿綆鐨勶細(xì)

Phase 1

(a) A proposer selects a proposal number n and sends a prepare request with number n to a majority of acceptors.

(b) If an acceptor receives a prepare request with number n greater than that of any prepare request to which it has already responded, then it responds to the request with a promise not to accept any more proposals numbered less than n and with the highest-numbered pro-posal (if any) that it has accepted.

Phase 2

(a) If the proposer receives a response to its prepare requests (numbered n) from a majority of acceptors, then it sends an accept request to each of those acceptors for a proposal numbered n with a value v , where v is the value of the highest-numbered proposal among the responses, or is any value if the responses reported no proposals.

(b) If an acceptor receives an accept request for a proposal numbered n, it accepts the proposal unless it has already responded to a prepare request having a number greater than n.

鍊熺敤paxos鍥捐В鏂囦腑鐨勬祦紼嬪浘鍙鎷負(fù)錛?/p>

瀹炰緥鍙?qiáng)璇﹁?/h2>

Paxos涓湁涓夌被瑙掕壊Proposer銆?code>Acceptor鍙?code>Learner錛屼富瑕佷氦浜掕繃紼嬪湪Proposer鍜?code>Acceptor涔嬮棿銆?/p>

Proposer涓?code>Acceptor涔嬮棿鐨勪氦浜掍富瑕佹湁4綾繪秷鎭氫俊錛屽涓嬪浘錛?/p>

榪?綾繪秷鎭搴斾簬paxos綆楁硶鐨勪袱涓樁孌?涓繃紼嬶細(xì)

  • phase 1
    • a) proposer鍚戠綉緇滃唴瓚呰繃鍗婃暟鐨刟cceptor鍙戦乸repare娑堟伅
    • b) acceptor姝e父鎯呭喌涓嬪洖澶峱romise娑堟伅
  • phase 2
    • a) 鍦ㄦ湁瓚沖澶歛cceptor鍥炲promise娑堟伅鏃訛紝proposer鍙戦乤ccept娑堟伅
    • b) 姝e父鎯呭喌涓媋cceptor鍥炲accepted娑堟伅

鍥犱負(fù)鍦ㄦ暣涓繃紼嬩腑鍙兘鏈夊叾浠杙roposer閽堝鍚屼竴浠朵簨鎯呭彂鍑轟互涓婅姹傦紝鎵浠ュ湪姣忎釜榪囩▼涓兘浼?xì)鏈変簺鐗箤D婃儏鍐靛鐞嗭紝榪欎篃鏄負(fù)浜?jiǎn)杈炬垚涓鑷存ф墍鍋氱殑浜嬫儏銆傚鏋滃湪鏁翠釜榪囩▼涓病鏈夊叾浠杙roposer鏉ョ珵浜夛紝閭d箞榪欎釜鎿嶄綔鐨勭粨鏋滃氨鏄‘瀹氭棤寮傝鐨勩備絾鏄鏋滄湁鍏朵粬proposer鐨勮瘽錛屾儏鍐靛氨涓嶄竴鏍蜂簡(jiǎn)銆?/p>

浠?a >paxos涓枃wiki涓婄殑渚嬪瓙涓轟緥銆傜畝鍗曟潵璇磋渚嬪瓙浠ヨ嫢騫蹭釜璁憳鎻愯紼庢敹錛岀‘瀹氭渶緇堥氳繃鐨勬硶妗堢◣鏀舵瘮渚嬨?/p>

浠ヤ笅鍥句腑鍩烘湰鍙敾鍑簆roposer涓庝竴涓猘cceptor鐨勪氦浜掋傛椂闂存爣蹇桾2鎬繪槸鍦═1鍚庨潰銆俻ropose number綆縐癗銆?/p>

鎯呭喌涔嬩竴濡備笅鍥撅細(xì)

A3鍦═1鍙戝嚭accepted緇橝1錛岀劧鍚庡湪T2鏀跺埌A5鐨刾repare錛屽湪T3鐨勬椂鍊橝1鎵嶉氱煡A5鏈緇堢粨鏋?紼庣巼10%)銆傝繖閲屼細(xì)鏈変袱縐嶆儏鍐碉細(xì)

  • A5鍙戞潵鐨凬5灝忎簬A1鍙戝嚭鍘葷殑N1錛岄偅涔圓3鐩存帴鎷掔粷(reject)A5
  • A5鍙戞潵鐨凬5澶т簬A1鍙戝嚭鍘葷殑N1錛岄偅涔圓3鍥炲promise錛屼絾甯︿笂A1鐨?N1, 10%)

榪欓噷鍙互涓巔axos嫻佺▼鍥懼搴旇搗鏉ワ紝鏇村ソ鐞嗚В銆?strong>acceptor浼?xì)璁板?MaxN, AcceptN, AcceptV)銆?/p>

A5鍦ㄦ敹鍒皃romise鍚庯紝鍚庣畫(huà)鐨勬祦紼嬪彲浠ラ『鍒╄繘琛屻備絾鏄彂鍑篴ccept鏃訛紝鍥犱負(fù)鏀跺埌浜?AcceptN, AcceptV)錛屾墍浠ヤ細(xì)鍙栨渶澶х殑AcceptN瀵瑰簲鐨凙cceptV錛屼緥瀛愪腑涔熷氨鏄疉1鐨?0%浣滀負(fù)AcceptV銆傚鏋滃湪鏀跺埌promise鏃舵病鏈夊彂鐜版湁鍏朵粬宸茶褰曠殑AcceptV錛屽垯鍏跺煎彲浠ョ敱鑷繁鍐沖畾銆?/p>

閽堝浠ヤ笂A1鍜孉5鍐茬獊鐨勬儏鍐碉紝鏈緇圓1鍜孉5閮戒細(xì)騫挎挱鎺ュ彈鐨勫間負(fù)10%銆?/p>

鍏跺疄4涓繃紼嬩腑瀵逛簬acceptor鑰岃█錛屽湪鍥炲promise鍜宎ccepted鏃剁敱浜庨兘鍙兘鍥犱負(fù)鍏朵粬proposer鐨勪粙鍏ヨ屽鑷寸壒孌婂鐞嗐傛墍浠ュ熀鏈笂鐪嬪湪榪欎袱涓椂闂寸偣鏀跺埌鍏朵粬proposer鐨勮姹傛椂灝卞彲浠ヤ簡(jiǎn)瑙f暣涓畻娉曚簡(jiǎn)銆備緥濡傚湪鍥炲promise鏃跺垯鍙兘鍥犱負(fù)proposer鍙戞潵鐨凬涓嶅澶ц宺eject錛?/p>

濡傛灉鍦ㄥ彂accepted娑堟伅鏃訛紝瀵瑰叾浠栨洿澶鐨刾roposer鍙戝嚭榪噋romise錛岄偅涔堜篃浼?xì)reject璇roposer鍙戝嚭鐨刟ccept錛屽鍥撅細(xì)

榪欎釜瀵瑰簲浜嶱hase 2 b)錛?/p>

it accepts the proposal unless it has already responded to a prepare request having a number greater than n.

鎬葷粨

Leslie Lamport娌℃湁鐢ㄦ暟瀛︽弿榪癙axos錛屼絾鏄粬鐢ㄨ嫳鏂囬槓榪板緱寰堟竻鏅般傚皢Paxos鐨勪袱涓狿hase鐨勫唴瀹圭悊瑙f竻妤氾紝鏁翠釜綆楁硶榪囩▼榪樻槸涓嶅鏉傜殑銆?/p>

鑷充簬Paxos涓竴鐩存彁鍒扮殑涓涓叏灞鍞竴涓旈掑鐨刾roposer number錛屽叾濡備綍瀹炵幇錛屽紩鐢ㄥ涓嬶細(xì)

濡備綍浜х敓鍞竴鐨勭紪鍙峰憿錛熷湪銆奝axos made simple銆嬩腑鎻愬埌鐨勬槸璁╂墍鏈夌殑Proposer閮戒粠涓嶇浉浜ょ殑鏁版嵁闆嗗悎涓繘琛岄夋嫨錛屼緥濡傜郴緇熸湁5涓狿roposer錛屽垯鍙負(fù)姣忎竴涓狿roposer鍒嗛厤涓涓爣璇唈(0~4)錛屽垯姣忎竴涓猵roposer姣忔鎻愬嚭鍐寵鐨勭紪鍙峰彲浠ヤ負(fù)5*i + j(i鍙互鐢ㄦ潵琛ㄧず鎻愬嚭璁鐨勬鏁?

鍙傝冩枃妗?/h2>

]]>娣樺疂鍒嗗竷寮忛厤緗鐞嗘湇鍔iamondhttp://m.shnenglu.com/kevinlynx/archive/2014/10/12/208549.htmlKevin LynxKevin LynxSun, 12 Oct 2014 04:57:00 GMThttp://m.shnenglu.com/kevinlynx/archive/2014/10/12/208549.htmlhttp://m.shnenglu.com/kevinlynx/comments/208549.htmlhttp://m.shnenglu.com/kevinlynx/archive/2014/10/12/208549.html#Feedback4http://m.shnenglu.com/kevinlynx/comments/commentRss/208549.htmlhttp://m.shnenglu.com/kevinlynx/services/trackbacks/208549.html

鍦ㄤ竴涓垎甯冨紡鐜涓紝鍚岀被鍨嬬殑鏈嶅姟寰寰浼?xì)閮ň|插緢澶氬疄渚嬨傝繖浜涘疄渚嬩嬌鐢ㄤ簡(jiǎn)涓浜涢厤緗紝涓轟簡(jiǎn)鏇村ソ鍦扮淮鎶よ繖浜涢厤緗氨浜х敓浜?jiǎn)閰嵕|鐞嗘湇鍔°傞氳繃榪欎釜鏈嶅姟鍙互杞繪澗鍦扮鐞嗚繖浜涘簲鐢ㄦ湇鍔$殑閰嶇疆闂銆傚簲鐢ㄥ満鏅彲姒傛嫭涓猴細(xì)

zookeeper鐨勪竴縐嶅簲鐢ㄥ氨鏄垎甯冨紡閰嶇疆綆$悊(鍩轟簬ZooKeeper鐨勯厤緗俊鎭瓨鍌ㄦ柟妗堢殑璁捐涓庡疄鐜?/a>)銆傜櫨搴︿篃鏈夌被浼肩殑瀹炵幇錛?a >disconf銆?/p>

Diamond鍒欐槸娣樺疂寮婧愮殑涓縐嶅垎甯冨紡閰嶇疆綆$悊鏈嶅姟鐨勫疄鐜般侱iamond鏈川涓婃槸涓涓狫ava鍐欑殑Web搴旂敤錛屽叾瀵瑰鎻愪緵鎺ュ彛閮芥槸鍩轟簬HTTP鍗忚鐨勶紝鍦ㄩ槄璇諱唬鐮佹椂鍙互浠庡疄鐜板悇涓帴鍙g殑controller鍏ユ墜銆?/p>

鍒嗗竷寮忛厤緗鐞?/h2>

鍒嗗竷寮忛厤緗鐞嗙殑鏈川鍩烘湰涓婂氨鏄竴縐?strong>鎺ㄩ?璁㈤槄妯″紡鐨勮繍鐢ㄣ傞厤緗殑搴旂敤鏂規(guī)槸璁㈤槄鑰咃紝閰嶇疆綆$悊鏈嶅姟鍒欐槸鎺ㄩ佹柟銆傛鎷負(fù)涓嬪浘錛?/p>

鍏朵腑錛屽鎴風(fēng)鍖呮嫭綆$悊浜哄憳publish鏁版嵁鍒伴厤緗鐞嗘湇鍔★紝鍙互鐞嗚В涓烘坊鍔?鏇存柊鏁版嵁錛涢厤緗鐞嗘湇鍔otify鏁版嵁鍒拌闃呰咃紝鍙互鐞嗚В涓烘帹閫併?/p>

閰嶇疆綆$悊鏈嶅姟寰寰浼?xì)灏佽涓涓鎴風(fēng)搴擄紝搴旂敤鏂瑰垯鏄熀浜庤搴撲笌閰嶇疆綆$悊鏈嶅姟榪涜浜や簰銆傚湪瀹為檯瀹炵幇鏃訛紝瀹㈡埛绔簱鍙兘鏄富鍔ㄦ媺鍙?pull)鏁版嵁錛屼絾瀵逛簬搴旂敤鏂硅岃█錛屼竴鑸槸涓縐嶄簨浠墮氱煡鏂瑰紡銆?/p>

Diamond涓殑鏁版嵁鏄畝鍗曠殑key-value緇撴瀯銆傚簲鐢ㄦ柟璁㈤槄鏁版嵁鍒欐槸鍩轟簬key鏉ヨ闃咃紝鏈闃呯殑鏁版嵁褰撶劧涓嶄細(xì)琚帹閫併傛暟鎹粠綾誨瀷涓婂張鍒掑垎涓鴻仛鍚堝拰闈炶仛鍚堛傚洜涓烘暟鎹帹閫佽呭彲鑳藉緢澶氾紝鍦ㄦ暣涓垎甯冨紡鐜涓紝鍙兘鏈夊涓帹閫佽呭湪鎺ㄩ佺浉鍚宬ey鐨勬暟鎹紝榪欎簺鏁版嵁濡傛灉鏄仛鍚堢殑錛岄偅涔堟墍鏈夎繖浜涙帹閫佽呮帹閫佺殑鏁版嵁浼?xì)琚悎迤堝湪涓璧鳳紱鍙嶄箣濡傛灉鏄潪鑱氬悎鐨勶紝鍒欎細(xì)鍑虹幇瑕嗙洊銆?/p>

鏁版嵁鐨勬潵婧愬彲鑳芥槸浜哄伐閫氳繃綆$悊绔綍鍏ワ紝涔熷彲鑳芥槸鍏朵粬鏈嶅姟閫氳繃閰嶇疆綆$悊鏈嶅姟鐨勬帹閫佹帴鍙h嚜鍔ㄥ綍鍏ャ?/p>

鏋舵瀯鍙?qiáng)瀹炵?/h2>

Diamond鏈嶅姟鏄竴涓泦緹わ紝鏄竴涓幓闄や簡(jiǎn)鍗曠偣鐨勫崗浣滈泦緹ゃ傚鍥撅細(xì)

鍥句腑鍙垎涓轟互涓嬮儴鍒嗚瑙o細(xì)

鏈嶅姟涔嬮棿鍚屾

Diamond鏈嶅姟闆嗙兢姣忎竴涓疄渚嬮兘鍙互瀵瑰瀹屾暣鍦版彁渚涙湇鍔★紝閭d箞鎰忓懗鐫姣忎釜瀹炰緥涓婇兘鏈夋暣涓泦緹ょ淮鎶ょ殑鏁版嵁銆侱iamond鏈変袱縐嶆柟寮忎繚璇佽繖涓鐐癸細(xì)

  • 浠諱綍涓涓疄渚嬮兘鏈夊叾浠栧疄渚嬬殑鍦板潃錛涗換浣曚竴涓疄渚嬩笂鐨勬暟鎹彉鏇存椂錛岄兘浼?xì)灏嗘敼鍙樼殑鏁版嵁鍚屾鍒癿ysql涓婏紝鐒跺悗閫氱煡鍏朵粬鎵鏈夊疄渚嬩粠mysql涓婅繘琛屼竴嬈℃暟鎹媺鍙?DumpService::dump)錛岃繖涓繃紼嬪彧鎷夊彇鏀瑰彉?shù)簡(jiǎn)鐨勬暟鎹?/li>
  • 浠諱綍涓涓疄渚嬪惎鍔ㄥ悗閮戒細(xì)浠ヨ緝闀跨殑鏃墮棿闂撮殧錛堝嚑灝忔椂錛夛紝浠巑ysql榪涜涓嬈″叏閲忕殑鏁版嵁鎷夊彇(DumpAllProcessor)

瀹炵幇涓婁負(fù)浜?jiǎn)涓鑷存э紝閫氱煡鍏朵粬瀹炰緥瀹為檯涓婁篃鍖呭惈鑷繁銆備互鏈嶅姟鍣ㄦ敹鍒版坊鍔犺仛鍚堟暟鎹負(fù)渚嬶紝澶勭悊榪囩▼澶ц嚧涓猴細(xì)

DatumController::addDatum // /datum.do?method=addDatum
    PersistService::addAggrConfigInfo 
    MergeDatumService::addMergeTask // 娣誨姞涓涓狹ergeDataTask錛屽紓姝ュ鐞?

MergeTaskProcessor::process
    PersistService::insertOrUpdate
        EventDispatcher.fireEvent(new ConfigDataChangeEvent // 媧懼彂涓涓狢onfigDataChangeEvent浜嬩歡

NotifyService::onEvent // 鎺ユ敹浜嬩歡騫跺鐞?
    TaskManager::addTask(..., new NotifyTask // 鐢辨錛屽綋鏁版嵁鍙戠敓鍙樺姩錛屽垯鏈緇堝垱寤轟簡(jiǎn)涓涓狽oticyTask

// NotifyTask鍚屾牱寮傛澶勭悊
NotifyTaskProcessor::process
    foreach server in serverList // 鍖呭惈鑷繁
        notifyToDump // 璋冪敤 /notify.do?method=notifyConfigInfo 浠巑ysql鏇存柊鍙樺姩鐨勬暟鎹?

铏界劧Diamond鍘婚櫎浜?jiǎn)鍗曠倸w棶棰橈紝涓嶈繃闂閮戒笅闄嶅埌浜?jiǎn)mysql涓娿備絾鐢變簬鍏朵綔涓洪厤緗鐞嗙殑瀹氫綅錛屽叾鏁版嵁閲忓氨mysql鐨勫簲鐢ㄨ岃█綆楀皬鐨勪簡(jiǎn)錛屾墍浠ュ彲浠ヤ竴瀹氱▼搴︿笂淇濊瘉鏁翠釜鏈嶅姟鐨勫彲鐢ㄦс?/p>

鏁版嵁涓鑷存?/h3>

鐢變簬Diamond鏈嶅姟鍣ㄦ病鏈塵aster錛屼換浣曚竴涓疄渚嬮兘鍙互璇誨啓鏁版嵁錛岄偅涔堥拡瀵瑰悓涓涓猭ey鐨勬暟鎹垯鍙兘闈復(fù)鍐茬獊銆傝繖閲屽簲璇ユ槸閫氳繃mysql鏉ヤ繚璇佹暟鎹殑涓鑷存с傛瘡涓嬈″鎴風(fēng)璇鋒眰鍐欐暟鎹椂錛孌iamond閮藉皢鍐欒姹傛姇閫掔粰mysql錛岀劧鍚庨氱煡闆嗙兢鍐呮墍鏈塂iamond瀹炰緥錛堝寘鎷嚜宸憋級(jí)浠巑ysql鎷夊彇鏁版嵁銆傚綋鐒?dòng)灱屾媺鍙栨暟鎹垯鍙兘涓嶆槸姣忎竴嬈″啓鍏ラ兘鑳芥媺鍑烘潵錛屼篃灝辨槸鏈緇堜竴鑷存с?/p>

Diamond涓病鏈夋妸鏁版嵁鏀懼叆鍐呭瓨錛屼絾浼?xì)鏀惧埌鏈湴鏂囦欢銆傚浜庡鎴風(fēng)鐨勮鎿嶄綔鑰岃█錛屽垯鏄洿鎺ヨ繑鍥炴湰鍦版枃浠墮噷鐨勬暟鎹?/p>

鏈嶅姟瀹炰緥鍒楄〃

Diamond鏈嶅姟瀹炰緥鍒楄〃鏄竴浠介潤(rùn)鎬佹暟鎹紝鐩存帴灝嗘瘡涓疄渚嬬殑鍦板潃瀛樻斁鍦ㄤ竴涓獁eb server涓娿傛棤璁烘槸Diamond鏈嶅姟榪樻槸瀹㈡埛绔兘浠庤web server涓婂彇鍑哄疄渚嬪垪琛ㄣ?/p>

瀵逛簬瀹㈡埛绔岃█錛屽綋鍏跺彇鍑轟簡(jiǎn)璇ュ垪琛ㄥ悗錛屽垯鏄殢鏈洪夋嫨涓涓妭鐐?ServerListManager.java)錛屼互鍚庣殑璇鋒眰閮戒細(xì)鍙戝線璇ヨ妭鐐廣?/p>

鏁版嵁鍚屾

瀹㈡埛绔簱涓互鍥哄畾鏃墮棿闂撮殧浠庢湇鍔″櫒鎷夊彇鏁版嵁(ClientWorker::ClientWorker錛?code>ClientWorker::checkServerConfigInfo)銆傚彧鏈夊簲鐢ㄦ柟鍏沖績(jī)鐨勬暟鎹墠鍙兘琚媺鍙栥傚彟澶栵紝涓轟簡(jiǎn)鏁版嵁鎺ㄩ佺殑鍙?qiáng)鏃跺Q孌iamond榪樹(shù)嬌鐢ㄤ簡(jiǎn)涓縐峫ong polling鐨勬妧鏈紝鍏跺疄涔熸槸涓轟簡(jiǎn)紿佺牬HTTP鍗忚鐨勫眬闄愭с?em>濡傛灉鏁翠釜鏈嶅姟鏄熀浜嶵CP鐨勮嚜瀹氫箟鍗忚錛屽鎴風(fēng)涓庢湇鍔″櫒淇濇寔闀胯繛鎺ュ垯娌℃湁榪欎簺闂銆?/p>

鏁版嵁鐨勫彉鏇?/h3>

Diamond涓緢澶氭搷浣滈兘浼?xì)妫鏌ユ暟鎹槸鍚﹀彂鐢熶簡(jiǎn)鍙樺寲銆傛爣璇嗘暟鎹彉鍖栧垯鏄熀浜庢暟鎹搴旂殑MD5鍊兼潵瀹炵幇鐨勩?/p>

瀹圭伨

鍦ㄦ暣涓狣iamond緋葷粺涓紝鍑犱釜瑙掕壊涓轟簡(jiǎn)鎻愰珮瀹圭伨鎬э紝閮芥湁鑷繁鐨勭紦瀛橈紝姒傛嫭涓轟笅鍥撅細(xì)

姣忎竴涓鑹插嚭闂鏃訛紝閮藉彲浠ュ敖閲忎繚璇佸鎴風(fēng)瀵瑰簲鐢ㄥ眰鎻愪緵鏈嶅姟銆?/p>

鍙傝冩枃妗?/h2>

]]> 青青草原综合久久大伊人导航_色综合久久天天综合_日日噜噜夜夜狠狠久久丁香五月_热久久这里只有精品
  • <ins id="pjuwb"></ins>
    <blockquote id="pjuwb"><pre id="pjuwb"></pre></blockquote>
      <noscript id="pjuwb"></noscript>
            <sup id="pjuwb"><pre id="pjuwb"></pre></sup>
              <dd id="pjuwb"></dd>
              <abbr id="pjuwb"></abbr>
              亚洲精品中文在线| 免费欧美在线| 精品va天堂亚洲国产| 欧美一区二区三区视频| 久久久精品欧美丰满| 亚洲国产精品一区二区www在线| 欧美另类专区| 亚洲综合色视频| 亚洲精品久久久久| 国产精品亚洲成人| 久久亚洲一区二区| 午夜精品国产精品大乳美女| 国际精品欧美精品| 中文国产成人精品久久一| 国产精品网站在线| 国产精品美女久久久久久2018| 欧美www在线| 久久国产精品一区二区| 一区二区三区四区五区精品| 免费欧美日韩国产三级电影| 先锋资源久久| 亚洲综合大片69999| 日韩西西人体444www| 在线播放中文一区| 国产亚洲精品bt天堂精选| 国产精品国产三级国产专播精品人 | 久久久久99精品国产片| 久久乐国产精品| 欧美在线观看视频一区二区三区| 在线视频你懂得一区二区三区| 亚洲人精品午夜| 亚洲精品久久久蜜桃| 亚洲国产精品一区二区尤物区| 一区二区不卡在线视频 午夜欧美不卡在 | 国产精品青草久久| 在线观看一区视频| 亚洲国产91精品在线观看| 一区二区av在线| 亚洲第一福利在线观看| 免费成人激情视频| 亚洲自拍另类| 欧美人与禽猛交乱配| 激情成人亚洲| 欧美诱惑福利视频| 一本色道久久综合亚洲精品按摩 | 性视频1819p久久| av不卡在线| 亚洲视屏一区| 亚洲一区二区三区激情| 亚洲一区二区三区影院| 美女精品一区| 欧美午夜免费影院| 国产欧美日韩一区二区三区| 国产一区二区三区日韩| 国产精品99久久久久久久女警| 欧美激情精品久久久久久| 久久精品99国产精品日本| 免费不卡亚洲欧美| 精品动漫一区二区| 久久国产黑丝| 欧美丰满高潮xxxx喷水动漫| 亚洲国产精品电影| 一区二区三区www| 欧美激情黄色片| 国产农村妇女精品一二区| 夜夜躁日日躁狠狠久久88av| 亚洲日韩视频| 欧美凹凸一区二区三区视频| 亚洲国产欧美一区| 亚洲一级片在线观看| 欧美一区=区| 亚洲一本视频| 国产欧美日韩视频在线观看| 香蕉久久夜色精品国产使用方法| 在线视频日韩精品| 久久一本综合频道| 亚洲国产高清一区| 欧美黄色大片网站| 亚洲国产成人av| 欧美电影在线观看完整版| 亚洲激情校园春色| 亚洲精品一区在线观看| 欧美一区日韩一区| 在线观看成人网| 亚洲福利视频专区| 欧美日韩亚洲成人| 亚洲欧洲在线一区| 亚洲精品欧美在线| 国产精品系列在线| 开心色5月久久精品| 亚洲午夜激情网页| 国产一区二区黄色| 欧美激情a∨在线视频播放| 欧美国产专区| 久久国产精品毛片| 亚洲一区二区成人在线观看| 国产麻豆成人精品| 亚洲在线观看| 欧美在线播放| 国产一区二区三区在线观看免费视频 | 久久综合成人精品亚洲另类欧美| 妖精视频成人观看www| 国产精品chinese| 久久久精品国产一区二区三区| 蜜桃久久av一区| 亚洲网站视频福利| 久久久久久久一区| 韩国v欧美v日本v亚洲v| 国产精品初高中精品久久| 久久久久国产精品一区| 亚洲欧美日韩国产成人精品影院| 一区在线影院| 一本一本久久a久久精品牛牛影视| 国产日韩视频一区二区三区| 亚洲一区二区三区在线| 欧美伊人久久| 亚洲欧美变态国产另类| 99精品视频免费观看视频| 国产一区二区黄色| 亚洲一区二区三区免费视频| 亚洲精品乱码久久久久久黑人| 久久蜜臀精品av| 校园春色综合网| 午夜欧美视频| 久久国产精品亚洲77777| 在线视频一区二区| 免费日本视频一区| 久久一区亚洲| 国产日韩欧美在线观看| 中文在线不卡| 亚洲视频一区二区| 欧美成人亚洲成人| 欧美成人综合| 亚洲国内欧美| 免费av成人在线| 欧美成人国产| 欧美日韩系列| 亚洲另类黄色| 日韩亚洲欧美成人一区| 麻豆av一区二区三区| 久热这里只精品99re8久| 国产欧美日韩亚洲一区二区三区| 在线亚洲高清视频| 欧美视频日韩视频| 久久精品国产免费| 欧美激情一区二区三区全黄| 香蕉久久夜色精品| 国产精品久久久久一区| 亚洲欧美日韩国产一区| 久久国产加勒比精品无码| 国产精品亚洲网站| 亚洲欧美日韩成人高清在线一区| 性欧美8khd高清极品| 国产精品区一区二区三| 亚洲一区二区三区中文字幕在线| 午夜国产精品视频| 国产美女精品一区二区三区 | 亚洲欧美国产另类| 国产精品久久久久91| 亚洲欧美影音先锋| 久久久久久久999| 亚洲国产综合91精品麻豆| 欧美大色视频| 一区二区三区免费观看| 欧美一级黄色录像| 在线免费观看成人网| 欧美黄色精品| 亚洲一级特黄| 蜜桃久久av一区| 一区二区三区久久网| 国产精品视频九色porn| 久久精品成人| 亚洲精品国产精品乱码不99按摩 | 国产精品大片| 羞羞色国产精品| 欧美成人中文字幕| 亚洲一区免费在线观看| 国产亚洲欧美激情| 美日韩在线观看| 亚洲欧美日韩精品一区二区| 久久综合九色综合欧美狠狠| 亚洲精品免费网站| 国产色视频一区| 欧美精品一区二区三区在线看午夜 | 亚洲香蕉伊综合在人在线视看| 国产人成精品一区二区三| 欧美jizzhd精品欧美巨大免费| 一本久久a久久免费精品不卡| 久久久成人精品| 亚洲一区二区三区高清| 韩国成人福利片在线播放| 欧美日韩人人澡狠狠躁视频| 久久福利精品| 99热免费精品在线观看| 久久人人爽人人爽爽久久| 亚洲一区三区视频在线观看| 尤妮丝一区二区裸体视频| 国产精品久久久久一区二区三区| 欧美波霸影院| 久久影院午夜论|