江苏快三开奖结果

隨筆 - 94  文章 - 0  trackbacks - 0
1. 電腦下載VBoxAdditions,網址:http://download.virtualbox.org/virtualbox/5.1.12/Oracle_VM_VirtualBox_Extension_Pack-5.1.12.vbox-extpack
2. 下載完成后雙擊打開,按照下一步的指示安裝完成。
3. 電腦下載VBoxAdditions,網址:http://download.virtualbox.org/virtualbox/5.1.12/VBoxGuestAdditions_5.1.12.iso
4. CentOS掛上光驅:
mkdir /mnt/cdrom
mount /dev/cdrom /mnt/cdrom
5. 將光驅內的文件夾復制到硬盤中。(如果直接在光驅中執行安裝,會因為權限問題導致無法安裝。)
cp -R /mnt/cdrom /usr/local/src/VBoxAdditions
6. (可選)安裝前需要設置安裝環境,如果已設置,那么這一步可以跳過:
yum install gcc
yum install make
yum install kernel-headers
yum install kernel-devel
7. 進入文件夾,開始安裝:./VBoxLinuxAdditions.run install

重啟系統!!!!!!!!!!!!!!!!!

8. 啟用共享文件夾:
mkdir /mnt/share
mount -t vboxsf vmshare /mnt/share
注釋:vmshare為visualbox界面配置里添加的共享文件路徑和名稱
ln -s /mnt/share /home/myshare (軟連接到用戶myshare下)

9. 成功!
————————————————
版權聲明:本文為CSDN博主「熊小憨」的原創文章,遵循 CC 4.0 BY-SA 版權協議,轉載請附上原文出處鏈接及本聲明。
原文鏈接:http://blog.csdn.net/suma110/article/details/54343686
posted @ 2020-02-16 19:51 長戟十三千 閱讀(4) | 評論 (0)編輯 收藏

MariaDB 數據庫管理系統是 MySQL 的一個分支,主要由開源社區在維護,采用 GPL 授權許可。開發這個分支的原因之一是:甲骨文公司收購了 MySQL 后,有將 MySQL 閉源的潛在風險,因此社區采用分支的方式來避開這個風險。MariaDB完全兼容mysql,使用方法也是一樣的

有的centos7已經默認安裝了Mariadb,可以查看自己的有沒有安裝,沒有安裝的再進行安裝,已經安裝了可以不用安裝也可以卸載了重裝。卸載命令 yum remove mariadb-server

 我的系統環境

 

1、安裝MariaDB

 通過yum安裝就行了。簡單快捷,安裝mariadb-server,默認依賴安裝mariadb,一個是服務端、一個是客戶端。

[root@mini ~]# yum install mariadb-server

 

2、配置MariaDB

1)安裝完成后首先要把MariaDB服務開啟,并設置為開機啟動

[root@mini ~]# systemctl start mariadb  # 開啟服務 [root@mini ~]# systemctl enable mariadb  # 設置為開機自啟動服務

2)首次安裝需要進行數據庫的配置,命令都和mysql的一樣

[root@mini ~]# mysql_secure_installation

 3)配置時出現的各個選項

復制代碼
Enter current password for root (enter for none):  # 輸入數據庫超級管理員root的密碼(注意不是系統root的密碼),第一次進入還沒有設置密碼則直接回車  Set root password? [Y/n]  # 設置密碼,y  New password:  # 新密碼 Re-enter new password:  # 再次輸入密碼  Remove anonymous users? [Y/n]  # 移除匿名用戶, y  Disallow root login remotely? [Y/n]  # 拒絕root遠程登錄,n,不管y/n,都會拒絕root遠程登錄  Remove test database and access to it? [Y/n]  # 刪除test數據庫,y:刪除。n:不刪除,數據庫中會有一個test數據庫,一般不需要  Reload privilege tables now? [Y/n]  # 重新加載權限表,y。或者重啟服務也許
復制代碼

4)測試是否能夠登錄成功,出現  MariaDB [(none)]> 就表示已經能夠正常登錄使用MariaDB數據庫了

復制代碼
[root@mini ~]# mysql -u root -p Enter password: Welcome to the MariaDB monitor.  Commands end with ; or \g. Your MariaDB connection id is 8 Server version: 5.5.60-MariaDB MariaDB Server  Copyright (c) 2000, 2018, Oracle, MariaDB Corporation Ab and others.  Type 'help;' or '\h' for help. Type '\c' to clear the current input statement.  MariaDB [(none)]>
復制代碼

 

3、設置MariaDB字符集為utf-8

 1)/etc/my.cnf 文件

在  [mysqld]  標簽下添加

init_connect='SET collation_connection = utf8_unicode_ci' init_connect='SET NAMES utf8' character-set-server=utf8 collation-server=utf8_unicode_ci skip-character-set-client-handshake

2)/etc/my.cnf.d/client.cnf 文件

在  [client]  標簽下添加

default-character-set=utf8

3)/etc/my.cnf.d/mysql-clients.cnf  文件

在  [mysql]  標簽下添加

default-character-set=utf8

4)重啟服務

[root@mini ~]# systemctl restart mariadb

5)進入mariadb查看字符集

 未配置字符集前
 配置字符集后

 

4、遠程鏈接mariadb數據庫

mariadb默認是拒絕 root 遠程登錄的。這里用的是 navicat 軟件連接數據庫

1)關閉防火墻

① 關閉防火墻 systemctl stop firewalld 

[root@mini ~]# systemctl stop firewalld

② 在不關閉防火墻的情況下,允許某端口的外來鏈接。步驟如下,開啟3306端口,重啟防火墻

復制代碼
[root@mini ~]# firewall-cmd --query-port=3306/tcp  # 查看3306端口是否開啟 no [root@mini ~]# firewall-cmd --zone=public --add-port=3306/tcp --permanent  # 開啟3306端口 success [root@mini ~]# firewall-cmd --reload  # 重啟防火墻 success [root@mini ~]# firewall-cmd --query-port=3306/tcp  # 查看3306端口是否開啟 yes
復制代碼

2)先查看mysql數據庫中的user表

復制代碼
[root@mini ~]# mysql -u root -p  # 先通過本地鏈接進入數據庫  MariaDB [(none)]> use mysql;  MariaDB [mysql]> select host, user from user; +-----------+------+ | host      | user | +-----------+------+ | 127.0.0.1 | root | | ::1       | root | | mini      | root | +-----------+------+ 3 rows in set (0.00 sec)
復制代碼

3)將與主機名相等的字段改為 "%" ,我的主機名為mini,

復制代碼
MariaDB [mysql]> update user set host='%' where host='mini'; Query OK, 1 row affected (0.00 sec) Rows matched: 1  Changed: 1  Warnings: 0  MariaDB [mysql]> select host, user from user; +-----------+------+ | host      | user | +-----------+------+ | %         | root | | 127.0.0.1 | root | | localhost | root | +-----------+------+ 3 rows in set (0.00 sec)
復制代碼

4)刷新權限表,或重啟mariadb服務,一下二選一即可

MariaDB [mysql]> flush privileges; Query OK, 0 rows affected (0.00 sec)
[root@mini ~]# systemctl restart mariadb

注意:刷新權限表是在數據庫中,重啟服務是在外部命令行中

 

6)重新遠程鏈接mariadb

 

posted @ 2020-02-15 11:45 長戟十三千 閱讀(2) | 評論 (0)編輯 收藏

1.何為隊列

TINGDAODUILIEXIANGXINDAJIADUIQIBINGBUMOSHENG,ZAIWOMENXIANSHISHENGHUOZHONGDUILIESUICHUKEJIAN,QUCHAOSHIJIEZHANG,NIHUIKANJIANDAJIADOUHUIYIPAIPAIDEZHANDEHAOHAODE,DENGDAIJIEZHANG,WEISHENMEYAOZHANDEYIPAIPAIDE,NIXIANGXIANGYIXIADAJIADOUMEIYOUSUZHI,YIWOFENGDESHANGQUJIEZHANG,BUJINRANGZHEGECHAOSHIBENGKUI,HUANHUIRONGYIZAOCHENGGEZHONGCAITASHIJIAN,DANGRANZHEXIESHIQISHIZAIWOMENXIANSHIZHONGYESHIHUIJINGCHANGFASHENG。

DANGRANZAIJISUANJISHIJIEZHONG,DUILIESHISHUYUYIZHONGSHUJUJIEGOU,DUILIECAIYONGDEFIFO(first in firstout),XINYUANSU(DENGDAIJINRUDUILIEDEYUANSU)ZONGSHIBEICHARUDAOWEIBU,ERDUQUDESHIHOUZONGSHICONGTOUBUKAISHIDUQU。ZAIJISUANZHONGDUILIEYIBANYONGLAIZUOPAIDUI(RUXIANCHENGCHIDEDENGDAIPAIDUI,SUODEDENGDAIPAIDUI),YONGLAIZUOJIEOU(SHENGCHANZHEXIAOFEIZHEMOSHI),YIBUDENGDENG。

2.jdk中的隊列

江苏快三开奖结果ZAIjdkZHONGDEDUILIEDOUSHIXIANLEjava.util.QueueJIEKOU,ZAIDUILIEZHONGYOUFENWEILIANGLEI,YILEISHIXIANCHENGBUANQUANDE,ArrayDeque,LinkedListDENGDENG,HUANYOUYILEIDOUZAIjava.util.concurrentBAOXIASHUYUXIANCHENGANQUAN,ERZAIWOMENZHENSHIDEHUANJINGZHONG,WOMENDEJIQIDOUSHISHUYUDUOXIANCHENG,DANGDUOXIANCHENGDUITONGYIGEDUILIEJINXINGPAIDUICAOZUODESHIHOU,RUGUOSHIYONGXIANCHENGBUANQUANHUICHUXIAN,FUGAISHUJU,SHUJUDIUSHIDENGWUFAYUCEDESHIQING,SUOYIWOMENZHEGESHIHOUZHINENGXUANZEXIANCHENGANQUANDEDUILIE。ZAIjdkZHONGTIGONGDEXIANCHENGANQUANDEDUILIEXIAMIANJIANDANLIEJUBUFENDUILIE:

隊列名字 是否加鎖 數據結構 關鍵技術點 是否有鎖 是否有界
ArrayBlockingQueue 數組array ReentrantLock 有鎖 有界
LinkedBlockingQueue 鏈表 ReentrantLock 有鎖 有界
LinkedTransferQueue 鏈表 CAS 無鎖 無界
ConcurrentLinkedQueue 鏈表 CAS 無鎖 無界

江苏快三开奖结果WOMENKEYIKANJIAN,WOMENWUSUODEDUILIESHIWUJIEDE,YOUSUODEDUILIESHIYOUJIEDE,ZHELIJIUHUISHEJIDAOYIGEWENTI,WOMENZAIZHENZHENGDEXIANSHANGHUANJINGZHONG,WUJIEDEDUILIE,DUIWOMENXITONGDEYINGXIANGBIJIAODA,YOUKENENGHUIDAOZHIWOMENNEICUNZHIJIEYICHU,SUOYIWOMENSHOUXIANDEPAICHUWUJIEDUILIE,DANGRANBINGBUSHIWUJIEDUILIEJIUMEIYONGLE,ZHISHIZAIMOUXIECHANGJINGXIADEPAICHU。QICIHUANSHENGXIAArrayBlockingQueue,LinkedBlockingQueueLIANGGEDUILIE,TAMENLIANGGEDOUSHIYONGReentrantLockKONGZHIDEXIANCHENGANQUAN,TAMENLIANGGEDEQUBIEYIGESHISHUZU,YIGESHILIANBIAO,ZAIDUILIEZHONG,YIBANHUOQUZHEGEDUILIEYUANSUZHIHOUJINJIEZHUHUIHUOQUXIAYIGEYUANSU,HUOZHEYICIHUOQUDUOGEDUILIEYUANSUDOUYOUKENENG,ERSHUZUZAINEICUNZHONGDIZHISHILIANXUDE,ZAICAOZUOXITONGZHONGHUIYOUHUANCUNDEYOUHUA(XIAMIANYEHUIJIESHAOHUANCUNXING),SUOYIFANGWENDESUDUHUILVESHENGYICHOU,WOMENYEHUIJINLIANGQUXUANZEArrayBlockingQueue。ERSHISHIZHENGMINGZAIHENDUODISANFANGDEKUANGJIAZHONG,BIRUZAOQIDElog4jYIBU,DOUSHIXUANZEDEArrayBlockingQueue。

DANGRANArrayBlockingQueue,YEYOUZIJIDEBIDUAN,JIUSHIXINGNENGBIJIAODI,WEISHENMEjdkHUIZENGJIAYIXIEWUSUODEDUILIE,QISHIJIUSHIWEILEZENGJIAXINGNENG,HENKUNAO,YOUXUYAOWUSUO,YOUXUYAOYOUJIE,ZHEGESHIHOUKONGPAHUIRENBUZHUSHUOYIJUNIZABUSHANGTIANNI?DANSHIHUANZHENYOURENSHANGTIANLE。

3.Disruptor

DisruptorJIUSHISHANGMIANSHUODENEIGETIAN,DisruptorSHIYINGGUOWAIHUIJIAOYIGONGSILMAXKAIFADEYIGEGAOXINGNENGDUILIE,BINGQIESHIYIGEKAIYUANDEBINGFAKUANGJIA,BINGHUODE2011Duke’sCHENGXUKUANGJIACHUANGXINJIANG。NENGGOUZAIWUSUODEQINGKUANGXIASHIXIANWANGLUODEQueueBINGFACAOZUO,JIYUDisruptorKAIFADEXITONGDANXIANCHENGNENGZHICHENGMEIMIAO600WANDINGDAN。MUQIAN,BAOKUOApache Storm、Camel、Log4j2DENGDENGZHIMINGDEKUANGJIADOUZAINEIBUJICHENGLEDisruptorYONGLAITIDAIjdkDEDUILIE,YICILAIHUODEGAOXINGNENG。

3.1為什么這么牛逼?

SHANGMIANYIJINGBADisruptorCHUICHULEHUALE,NIKENDINGHUICHANSHENGYIWEN,TAZHENDENENGYOUZHEMENIUBIMA,WODEHUIDASHIDANGRANDE,ZAIDisruptorZHONGYOUSANDASHAQI:

  • CAS
  • 消除偽共享
  • RingBuffer 有了這三大殺器,Disruptor才變得如此牛逼。

3.1.1鎖和CAS

江苏快三开奖结果WOMENArrayBlockingQueueWEISHENMEHUIBEIPAOQIDEYIDIAN,JIUSHIYINWEIYONGLEZHONGLIANGJIlockSUO,ZAIWOMENJIASUOGUOCHENGZHONGWOMENHUIBASUOGUAQI,JIESUOHOU,YOUHUIBAXIANCHENGHUIFU,ZHEYIGUOCHENGHUIYOUYIDINGDEKAIXIAO,BINGQIEWOMENYIDANMEIYOUHUOQUSUO,ZHEGEXIANCHENGJIUZHINENGYIZHIDENGDAI,ZHEGEXIANCHENGSHENMESHIYEBUNENGZUO。

CAS(compare and swap),GUMINGSIYIXIANBIJIAOZAIJIAOHUAN,YIBANSHIBIJIAOSHIFOUSHILAODEZHI,RUGUOSHIDEJINXINGJIAOHUANSHEZHI,DAJIASHUXILEGUANSUODERENDOUZHIDAOCASKEYIYONGLAISHIXIANLEGUANSUO,CASZHONGMEIYOUXIANCHENGDESHANGXIAWENQIEHUAN,JIANSHAOLEBUBIYAODEKAIXIAO。 ZHELISHIYONGJMH,YONGLIANGGEXIANCHENG,MEICI1YICIDIAOYONG,ZAIWOBENJISHANGJINXINGCESHI,DAIMARUXIA:

@BenchmarkMode({Mode.SampleTime}) @OutputTimeUnit(TimeUnit.MILLISECONDS) @Warmup(iterations=3, time = 5, timeUnit = TimeUnit.MILLISECONDS) @Measurement(iterations=1,batchSize = 100000000) @Threads(2) @Fork(1) @State(Scope.Benchmark) public class Myclass {     Lock lock = new ReentrantLock();     long i = 0;     AtomicLong atomicLong = new AtomicLong(0);     @Benchmark     public void measureLock() {         lock.lock();         i++;         lock.unlock();     }     @Benchmark     public void measureCAS() {         atomicLong.incrementAndGet();     }     @Benchmark     public void measureNoLock() {         i++;     } } 復制代碼

CESHICHULAIJIEGUORUXIA:

測試項目 測試結果
Lock 26000ms
CAS 4840ms
無鎖 197ms

KEYIKANJIANLockSHIWUWEISHU,CASSHISIWEISHU,WUSUOGENGXIAOSHISANWEISHU。 YOUCIWOMENKEYIZHIDAOLock>CAS>WUSUO。

ERWOMENDEDisruptorZHONGSHIYONGDEJIUSHICAS,TALIYONGCASJINXINGDUILIEZHONGDEYIXIEXIABIAOSHEZHI,JIANSHAOLESUODECHONGTU,TIGAOLEXINGNENG。

LINGWAIDUIYUjdkZHONGQITADEWUSUODUILIEYESHISHIYONGCAS,YUANZILEIYESHISHIYONGCAS。

3.1.2偽共享

TANDAOLEWEIGONGXIANGJIUBUDEBUSHUOJISUANJICPUHUANCUN,HUANCUNDAXIAOSHICPUDEZHONGYAOZHIBIAOZHIYI,ERQIEHUANCUNDEJIEGOUHEDAXIAODUICPUSUDUDEYINGXIANGFEICHANGDA,CPUNEIHUANCUNDEYUNXINGPINLVJIGAO,YIBANSHIHECHULIQITONGPINYUNZUO,GONGZUOXIAOLVYUANYUANDAYUXITONGNEICUNHEYINGPAN。SHIJIGONGZUOSHI,CPUWANGWANGXUYAOZHONGFUDUQUTONGYANGDESHUJUKUAI,ERHUANCUNRONGLIANGDEZENGDA,KEYIDAFUDUTISHENGCPUNEIBUDUQUSHUJUDEMINGZHONGLV,ERBUYONGZAIDAONEICUNHUOZHEYINGPANSHANGXUNZHAO,YICITIGAOXITONGXINGNENG。DANSHICONGCPUXINPIANMIANJIHECHENGBENDEYINSULAIKAOLV,HUANCUNDOUHENXIAO。

 

 

CPUHUANCUNKEYIFENWEIYIJIHUANCUN,ERJIHUANCUN,RUJINZHULIUCPUHUANYOUSANJIHUANCUN,SHENZHIYOUXIECPUHUANYOUSIJIHUANCUN。MEIYIJIHUANCUNZHONGSUOCHUCUNDEQUANBUSHUJUDOUSHIXIAYIJIHUANCUNDEYIBUFEN,ZHESANZHONGHUANCUNDEJISHUNANDUHEZHIZAOCHENGBENSHIXIANGDUIDIJIANDE,SUOYIQIRONGLIANGYESHIXIANGDUIDIZENGDE。

江苏快三开奖结果WEISHENMECPUHUIYOUL1、L2、L3ZHEYANGDEHUANCUNSHEJI?ZHUYAOSHIYINWEIXIANZAIDECHULIQITAIKUAILE,ERCONGNEICUNZHONGDUQUSHUJUSHIZAITAIMAN(YIGESHIYINWEINEICUNBENSHENSUDUBUGOU,LINGYIGESHIYINWEITALICPUTAIYUANLE,ZONGDELAISHUOXUYAORANGCPUDENGDAIJISHISHENZHIJIBAIGESHIZHONGZHOUQI),ZHEGESHIHOUWEILEBAOZHENGCPUDESUDU,JIUXUYAOYANCHIGENGXIAOSUDUGENGKUAIDENEICUNTIGONGBANGZHU,ERZHEJIUSHIHUANCUN。DUIZHEGEGANXINGQUKEYIBADIANNAOCPUCHAIXIALAI,ZIJIBAWANYIXIA。

江苏快三开奖结果MEIYICINITINGJIANintelFABUXINDEcpuSHENME,BIRUi7-7700k,8700k,DOUHUIDUIcpuHUANCUNDAXIAOJINXINGYOUHUA,GANXINGQUKEYIZIXINGXIALAISOUSUO,ZHEXIEDEFABUHUIHUOZHEFABUWENZHANG。

MartinHEMikeDE QConpresentationYANJIANGZHONGGEICHULEYIXIEMEIGEHUANCUNSHIJIAN:

從CPU到 大約需要的CPU周期 大約需要的時間
主存 約60-80納秒
QPI 總線傳輸(between sockets, not drawn) 約20ns
L3 cache 約40-45 cycles 約15ns
L2 cache 約10 cycles 約3ns
L1 cache 約3-4 cycles 約1ns
寄存器 1 cycle

緩存行

江苏快三开奖结果ZAIcpuDEDUOJIHUANCUNZHONG,BINGBUSHIYIDULIDEXIANGLAIBAOCUNDE,ERSHILEISIYIZHONGpageCaheDEYIZHONGCELVE,YIHUANCUNXINGLAIBAOCUN,ERHUANCUNXINGDEDAXIAOTONGCHANGSHI64ZIJIE,ZAIJavaZHONGLongSHI8GEZIJIE,SUOYIKEYICUNCHU8GELong,JUGELIZI,NIFANGWENYIGElongDEBIANLIANGDESHIHOU,TAHUIBABANGZHUZAIJIAZAI7GE,WOMENSHANGMIANSHUOWEISHENMEXUANZESHUZUBUXUANZELIANBIAO,YEJIUSHIZHEGEYUANYIN,ZAISHUZUZHONGKEYIYIKAOHUANCHONGXINGDEDAOHENKUAIDEFANGWEN。

 

江苏快三开奖结果HUANCUNXINGSHIWANNENGDEMA?NO,YINWEITAYIRANDAILAILEYIGEQUEDIAN,WOZAIZHELIJUGELIZISHUOMINGZHEGEQUEDIAN,KEYIXIANGXIANGYOUGESHUZUDUILIE,ArrayQueue,TADESHUJUJIEGOURUXIA:

class ArrayQueue{     long maxSize;     long currentIndex; } 復制代碼

江苏快三开奖结果DUIYUmaxSizeSHIWOMENYIKAISHIJIUDINGYIHAODE,SHUZUDEDAXIAO,DUIYUcurrentIndex,SHIBIAOZHIWOMENDANGQIANDUILIEDEWEIZHI,ZHEGEBIANHUABIJIAOKUAI,KEYIXIANGXIANGNIFANGWENmaxSizeDESHIHOU,SHIBUSHIBAcurrentIndexYEJIAZAIJINLAILE,ZHEGESHIHOU,QITAXIANCHENGGENGXINcurrentIndex,JIUHUIBAcpuZHONGDEHUANCUNXINGZHIWEIWUXIAO,QINGZHUYIZHESHICPUGUIDINGDE,TABINGBUSHIZHIBAcurrentIndexZHIWEIWUXIAO,RUGUOCISHIYOUJIXUFANGWENmaxSizeTAYIRANDEJIXUCONGNEICUNZHONGDUQU,DANSHIMaxSizeQUESHIWOMENYIKAISHIDINGYIHAODE,WOMENYINGGAIFANGWENHUANCUNJIKE,DANSHIQUEBEIWOMENJINGCHANGGAIBIANDEcurrentIndexSUOYINGXIANG。

 

 

Padding的魔法

江苏快三开奖结果WEILEJIEJUESHANGMIANHUANCUNXINGCHUXIANDEWENTI,ZAIDisruptorZHONGCAIYONGLEPaddingDEFANGSHI,

class LhsPadding {     protected long p1, p2, p3, p4, p5, p6, p7; }  class Value extends LhsPadding {     protected volatile long value; }  class RhsPadding extends Value {     protected long p9, p10, p11, p12, p13, p14, p15; } 復制代碼

江苏快三开奖结果QIZHONGDEValueJIUBEIQITAYIXIEWUYONGDElongBIANLIANGGEITIANCHONGLE。ZHEYANGNIXIUGAIValueDESHIHOU,JIUBUHUIYINGXIANGDAOQITABIANLIANGDEHUANCUNXING。

江苏快三开奖结果ZUIHOUSHUNBIANYITI,ZAIjdk8ZHONGTIGONGLE@ContendedDEZHUJIE,DANGRANYIBANLAISHUOZHIYUNXUJdkZHONGNEIBU,RUGUONIZIJISHIYONGNEIJIUDEPEIZHIJvmCANSHU -RestricContentended = fase,JIANGXIANZHIZHEGEZHUJIEZHIWEIQUXIAO。HENDUOWENZHANGFENXILEConcurrentHashMap,DANSHIDOUBAZHEGEZHUJIEGEIHULVEDIAOLE,ZAIConcurrentHashMapZHONGJIUSHIYONGLEZHEGEZHUJIE,ZAIConcurrentHashMapMEIGETONGDOUSHIDANDUDEYONGJISHUQIQUZUOJISUAN,ERZHEGEJISHUQIYOUYUSHIKEDOUZAIBIANHUA,SUOYIBEIYONGZHEGEZHUJIEJINXINGTIANCHONGHUANCUNXINGYOUHUA,YICILAIZENGJIAXINGNENG。

 

 

3.1.3RingBuffer

ZAIDisruptorZHONGCAIYONGLESHUZUDEFANGSHIBAOCUNLEWOMENDESHUJU,SHANGMIANWOMENYEJIESHAOLECAIYONGSHUZUBAOCUNWOMENFANGWENSHIHENHAODELIYONGHUANCUN,DANSHIZAIDisruptorZHONGJINYIBUXUANZECAIYONGLEHUANXINGSHUZUJINXINGBAOCUNSHUJU,YEJIUSHIRingBuffer。ZAIZHELIXIANSHUOMINGYIXIAHUANXINGSHUZUBINGBUSHIZHENZHENGDEHUANXINGSHUZU,ZAIRingBufferZHONGSHICAIYONGQUYUDEFANGSHIJINXINGFANGWENDE,BIRUSHUZUDAXIAOWEI 10,0FANGWENDESHISHUZUXIABIAOWEI0ZHEGEWEIZHI,QISHI10,20DENGFANGWENDEYESHISHUZUDEXIABIAOWEI0DEZHEGEWEIZHI。

江苏快三开奖结果SHIJISHANG,ZAIZHEXIEKUANGJIAZHONGQUYUBINGBUSHISHIYONG%YUNSUAN,DOUSHISHIYONGDE&YUYUNSUAN,ZHEJIUYAOQIUNISHEZHIDEDAXIAOYIBANSHI2DENCIFANGYEJIUSHI,10,100,1000DENGDENG,ZHEYANGJIANQU1DEHUAJIUSHI,1,11,111,JIUNENGHENHAODESHIYONGindex & (size -1),ZHEYANGLIYONGWEIYUNSUANJIUZENGJIALEFANGWENSUDU。 RUGUOZAIDisruptorZHONGNIBUYONG2DENCIFANGJINXINGDAXIAOSHEZHI,TAHUIPAOCHUbuffersizeBIXUWEI2DENCIFANGYICHANG。

DANGRANQIBUJINJIEJUELESHUZUKUAISUFANGWENDEWENTI,YEJIEJUELEBUXUYAOZAICIFENPEINEICUNDEWENTI,JIANSHAOLELAJIHUISHOU,YINWEIWOMEN0,10,20DENGDOUSHIZHIXINGDETONGYIPIANNEICUNQUYU,ZHEYANGJIUBUXUYAOZAICIFENPEINEICUN,PINFANDEBEIJVMLAJIHUISHOUQIHUISHOU。

 

 

江苏快三开奖结果ZICISANDASHAQIYIJINGSHUOWANLE,YOULEZHESANDASHAQIWEIDisruptorRUCIGAOXINGNENGDIANDINGLEJICHU。JIEXIALAIHUANHUIZAIJIANGJIERUHESHIYONGDisruptorHEDisruptorDEJUTIDEGONGZUOYUANLI。

3.2Disruptor怎么使用

XIAMIANJULEYIGEJIANDANDELIZI:

ublic static void main(String[] args) throws Exception {         // 隊列中的元素         class Element {             @Contended             private String value;               public String getValue() {                 return value;             }              public void setValue(String value) {                 this.value = value;             }         }          // 生產者的線程工廠         ThreadFactory threadFactory = new ThreadFactory() {             int i = 0;             @Override             public Thread newThread(Runnable r) {                 return new Thread(r, "simpleThread" + String.valueOf(i++));             }         };          // RingBuffer生產工廠,初始化RingBuffer的時候使用         EventFactory<Element> factory = new EventFactory<Element>() {             @Override             public Element newInstance() {                 return new Element();             }         };          // 處理Event的handler         EventHandler<Element> handler = new EventHandler<Element>() {             @Override             public void onEvent(Element element, long sequence, boolean endOfBatch) throws InterruptedException {                 System.out.println("Element: " + Thread.currentThread().getName() + ": " + element.getValue() + ": " + sequence); //                Thread.sleep(10000000);             }         };           // 阻塞策略         BlockingWaitStrategy strategy = new BlockingWaitStrategy();          // 指定RingBuffer的大小         int bufferSize = 8;          // 創建disruptor,采用單生產者模式         Disruptor<Element> disruptor = new Disruptor(factory, bufferSize, threadFactory, ProducerType.SINGLE, strategy);          // 設置EventHandler         disruptor.handleEventsWith(handler);          // 啟動disruptor的線程         disruptor.start();         for (int i = 0; i < 10; i++) {             disruptor.publishEvent((element, sequence) -> {                 System.out.println("之前的數據" + element.getValue() + "當前的sequence" + sequence);                 element.setValue("我是第" + sequence + "個");             });          }     } 復制代碼

ZAIDisruptorZHONGYOUJIGEBIJIAOGUANJIANDE: ThreadFactory:ZHESHIYIGEXIANCHENGGONGCHANG,YONGYUWOMENDisruptorZHONGSHENGCHANZHEXIAOFEIDESHIHOUXUYAODEXIANCHENG。 EventFactory:SHIJIANGONGCHANG,YONGYUCHANSHENGWOMENDUILIEYUANSUDEGONGCHANG,ZAIDisruptorZHONG,TAHUIZAICHUSHIHUADESHIHOUZHIJIETIANCHONGMANRingBuffer,YICIDAOWEI。 EventHandler:YONGYUCHULIEventDEhandler,ZHELIYIGEEventHandlerKEYIKANZUOSHIYIGEXIAOFEIZHE,DANSHIDUOGEEventHandlerTAMENDOUSHIDULIXIAOFEIDEDUILIE。 WorkHandler:YESHIYONGYUCHULIEventDEhandler,HESHANGMIANQUBIEZAIYU,DUOGEXIAOFEIZHEDOUSHIGONGXIANGTONGYIGEDUILIE。 WaitStrategy:DENGDAICELVE,ZAIDisruptorZHONGYOUDUOZHONGCELVE,LAIJUEDINGXIAOFEIZHEHUOXIAOFEISHI,RUGUOMEIYOUSHUJUCAIQUDECELVESHISHENME?XIAMIANJIANDANLIEJUYIXIADisruptorZHONGDEBUFENCELVE

  • BlockingWaitStrategy:TONGGUOXIANCHENGZUSAIDEFANGSHI,DENGDAISHENGCHANZHEHUANXING,BEIHUANXINGHOU,ZAIXUNHUANJIANCHAYILAIDEsequenceSHIFOUYIJINGXIAOFEI。

  • BusySpinWaitStrategy:XIANCHENGYIZHIZIXUANDENGDAI,KENENGBIJIAOHAOcpu

  • 江苏快三开奖结果LiteBlockingWaitStrategy:XIANCHENGZUSAIDENGDAISHENGCHANZHEHUANXING,YUBlockingWaitStrategyXIANGBI,QUBIEZAIsignalNeeded.getAndSet,RUGUOLIANGGEXIANCHENGTONGSHIFANGWENYIGEFANGWENwaitfor,YIGEFANGWENsignalAllSHI,KEYIJIANSHAOlockJIASUOCISHU.

  • LiteTimeoutBlockingWaitStrategy:YULiteBlockingWaitStrategyXIANGBI,SHEZHILEZUSAISHIJIAN,CHAOGUOSHIJIANHOUPAOYICHANG。

  • YieldingWaitStrategy:CHANGSHI100CI,RANHOUThread.yield()RANGCHUcpu

EventTranslator:SHIXIANZHEGEJIEKOUKEYIJIANGWOMENDEQITASHUJUJIEGOUZHUANHUANWEIZAIDisruptorZHONGLIUTONGDEEvent。

3.3工作原理

SHANGMIANYIJINGJIESHAOLECAS,JIANSHAOWEIGONGXIANG,RingBufferSANDASHAQI,JIESHAOXIALAISHUOYIXIADisruptorZHONGSHENGCHANZHEHEXIAOFEIZHEDEZHENGGELIUCHENG。

3.3.1生產者

江苏快三开奖结果DUIYUSHENGCHANZHELAISHUO,KEYIFENWEIDUOSHENGCHANZHEHEDANSHENGCHANZHE,YONGProducerType.Single,HEProducerType.MULTIQUFEN,DUOSHENGCHANZHEHEDANSHENGCHANZHELAISHUODUOLECAS,YINWEIDANSHENGCHANZHEYOUYUSHIDANXIANCHENG,SUOYIBUXUYAOBAOZHENGXIANCHENGANQUAN。

ZAIdisruptorZHONGTONGCHANGYONGdisruptor.publishEventHEdisruptor.publishEvents()JINXINGDANFAHEQUNFA。

江苏快三开奖结果ZAIdisruptorFABUYIGESHIJIANJINRUDUILIEXUYAOXIAMIANJIGEBUZOU:

  1. 首先獲取RingBuffer中下一個在RingBuffer上可以發布的位置,這個可以分為兩類:
  • 從來沒有寫過的位置
  • 已經被所有消費者讀過,可以在寫的位置。 如果沒有讀取到會一直嘗試去讀,disruptor做的很巧妙,并沒有一直占據CPU,而是通過LockSuport.park(),進行了一下將線程阻塞掛起操作,為的是不讓CPU一直進行這種空循環,不然其他線程都搶不到CPU時間片。
    獲取位置之后會進行cas進行搶占,如果是單線程就不需要。
  1. 接下來調用我們上面所介紹的EventTranslator將第一步中RingBuffer中那個位置的event交給EventTranslator進行重寫。
  2. 進行發布,在disruptor還有一個額外的數組用來記錄當前ringBuffer所在位置目前最新的序列號是多少,拿上面那個0,10,20舉例,寫到10的時候這個avliableBuffer就在對應的位置上記錄目前這個是屬于10,有什么用呢后面會介紹。進行發布的時候需要更新這個avliableBuffer,然后進行喚醒所有阻塞的生產者。

江苏快三开奖结果XIAMIANJIANDANHUAYIXIALIUCHENG,SHANGMIANWOMENNA10JULISHIBUDUIDE,YINWEIbufferSizeBIXUYAO2DENCIFANG,SUOYIWOMENZHELINABuffersize=8LAIJULI:XIAMIANJIESHAOLEDANGWOMENYIJINGpushLE8GEeventYEJIUSHIYIQUANDESHIHOU,JIEXIALAIZAIpush 3TIAOXIAOXIDEYIXIEGUOCHENG: 1.SHOUXIANDIAOYONGnext(3),WOMENDANGQIANZAI7ZHEGEWEIZHISHANGSUOYIJIEXIALAISANTIAOSHI8,9,10,QUYUYEJIUSHI0,1,2。 2.ZHONGXIE0,1,2ZHESANGENEICUNQUYUDESHUJU。 3.XIEavaliableBuffer。

 

 

DUILEBUZHIDAODAJIADUISHANGSHULIUCHENGSHIBUSHIHENSHUXINI,DUIDENEIJIUSHILEISIWOMENDE2PC,LIANGJIEDUANTIJIAO,XIANJINXINGRingBufferDEWEIZHISUODING,RANHOUZAIJINXINGTIJIAOHETONGZHIXIAOFEIZHE。JUTI2PCDEJIESHAOKEYICANZHAOWODELINGWAIYIPIANWENZHANG。

3.3.1消費者

DUIYUXIAOFEIZHELAISHUO,SHANGMIANJIESHAOLEFENWEILIANGZHONG,YIZHONGSHIDUOGEXIAOFEIZHEDULIXIAOFEI,YIZHONGSHIDUOGEXIAOFEIZHEXIAOFEITONGYIGEDUILIE,ZHELIJIESHAOYIXIAJIAOWEIFUZADEDUOGEXIAOFEIZHEXIAOFEITONGYIGEDUILIE,NENGLIJIEZHEGEYEJIUNENGLIJIEDULIXIAOFEI。 ZAIWOMENDEdisruptor.strat()FANGFAZHONGHUIQIDONGWOMENDEXIAOFEIZHEXIANCHENGYICILAIJINXINGHOUTAIXIAOFEI。ZAIXIAOFEIZHEZHONGYOULIANGGEDUILIEXUYAOWOMENGUANZHU,YIGESHISUOYOUXIAOFEIZHEGONGXIANGDEJINDUDUILIE,HUANYOUGESHIMEIGEXIAOFEIZHEDULIXIAOFEIJINDUDUILIE。 1.DUIXIAOFEIZHEGONGXIANGDUILIEJINXINGXIAYIGENextDECASQIANGZHAN,YIJIDUIZIJIXIAOFEIJINDUDEDUILIEBIAOJIDANGQIANJINDU。 2.WEIZIJISHENQINGKEDUDERingBufferDENextWEIZHI,ZHELIDESHENQINGBUJINJINSHISHENQINGDAOnext,YOUKENENGHUISHENQINGDAOBINextDADEYIGEFANWEI,ZUSAICELVEDESHENQINGDEGUOCHENGRUXIA:

  • 獲取生產者對RingBuffer最新寫的位置
  • 判斷其是否小于我要申請讀的位置
  • 如果大于則證明這個位置已經寫了,返回給生產者。
  • 如果小于證明還沒有寫到這個位置,在阻塞策略中會進行阻塞,其會在生產者提交階段進行喚醒。 3.對這個位置進行可讀校驗,因為你申請的位置可能是連續的,比如生產者目前在7,接下來申請讀,如果消費者已經把8和10這個序列號的位置寫進去了,但是9這個位置還沒來得及寫入,由于第一步會返回10,但是9其實是不能讀的,所以得把位置向下收縮到8。
    4.如果收縮完了之后比當前next要小,則繼續循環申請。 5.交給handler.onEvent()處理

YIYANGDEWOMENJUGELIZI,WOMENYAOSHENQINGnext=8ZHEGEWEIZHI。 1.SHOUXIANZAIGONGXIANGDUILIEQIANGZHANJINDU8,ZAIDULIDUILIEXIERUJINDU7 2.HUOQU8DEKEDUDEZUIDAWEIZHI,ZHELIGENJUBUTONGDECELVEJINXING,WOMENXUANZEZUSAI,YOUYUSHENGCHANZHESHENGCHANLE8,9,10,SUOYIFANHUIDESHI10,ZHEYANGHEHOUXUJIUBUXUYAOZAICIHEavaliableBufferJINXINGDUIBILE。 3.ZUIHOUJIAOGEIhandlerJINXINGCHULI。

 

4.Log4j中的Disruptor

XIAMIANDETUZHANXIANLELog4jSHIYONGDisruptor,ArrayBlockingQueueYIJITONGBUDELog4jTUNTULIANGDEDUIBI,KEYIKANJIANSHIYONGLEDisruptorWANBAOLEQITADE,DANGRANHUANYOUGENGDUODEKUANGJIASHIYONGLEDisruptor,ZHELIJIUBUZUOJIESHAOLE。

 

 


作者:咖啡拿鐵
鏈接:http://juejin.im/post/5b5f10d65188251ad06b78e3
來源:掘金
著作權歸作者所有。商業轉載請聯系作者獲得授權,非商業轉載請注明出處。
posted @ 2020-01-16 20:12 長戟十三千 閱讀(18) | 評論 (0)編輯 收藏
1、共享內存實現跨進程消息隊列:《UNIX網絡編程卷2》,消息隊列,p85
      offset識別結構體內容,防止重復加載內存地址變更。共享信號量或者無鎖環形隊列,MAGIC NUMBER 驗證,防止版本不一致。

2、虛擬實時:《linux內核設計與實現》, 進程調度,p43
      調度時使用時間記賬。虛擬運行時間 +=加權(上一幀運行時間); while {run get_task( min(虛擬運行時間) ) ;}(true);
     移動檢測時曾用到過異常移動的加權算法,與這個類似。每步移動異常加權,總量超過后,執行 禁止移動時間=異常總量/速度 的懲罰。

3、等待隊列:《linux內核設計與實現》, 進程調度,p50
   在讀列上自旋,沒有事件則調度等待,否則返回。

epoll源碼:自旋鎖+就緒隊列,mutex+紅黑樹數據
無限法則服務器:接口->協程+rpc->服務組件, 可灰更微服務,共享內存1s拉起,接口自動測試,全局鎖服務器用于獨占某些服務或操作。
ECS模式:word=system+entity; system=sys1+sys2+sysn; entity=componentN;
位標記的靜態數組:int info_flg; T vct_info; 《linux內核設計與實現》, 軟中斷,p111。 tasklet:利用靜態軟中斷,添加調度策略:高低優先級鏈表。ksoftirqd:每個cpu上低優先級內核線程池,處理高并發軟中斷,防止造成用戶線程饑餓。
posted @ 2020-01-16 16:32 長戟十三千 閱讀(21) | 評論 (0)編輯 收藏
     摘要: inline是C++關鍵字,在函數聲明或定義中,函數返回類型前加上關鍵字inline,即可以把函數指定為內聯函數。這樣可以解決一些頻繁調用的函數大量消耗棧空間(棧內存)的問題。關鍵字inline必須與函數定義放在一起才能使函數成為內聯函數,僅僅將inline放在函數聲明前面不起任何作用。inline是一種“用于實現”的關鍵字,而不是一種“用于聲明”的...  閱讀全文
posted @ 2020-01-13 11:28 長戟十三千 閱讀(13) | 評論 (0)編輯 收藏
     摘要: 3)下面的函數被用來計算某個整數的平方,它能實現預期設計目標嗎?如果不能,試回答存在什么問題:1234int square(volatile int *ptr){    return ((*ptr) * (*ptr));}3)這段代碼是個惡作劇。這段代碼的目的是用來返指針*ptr指向值的平方,但是,...  閱讀全文
posted @ 2020-01-13 11:22 長戟十三千 閱讀(10) | 評論 (0)編輯 收藏

前言

ZIJIEDUIQISHIWOMENCHUXUECYUYANJIUHUIJIECHUDAODEYIGEGAINIAN,DANSHIDAODISHENMESHIZIJIEDUIQI?DUIQIZHUNZEYOUSHISHENME?WEISHENMEYAOZIJIEDUIQINI?ZIJIEDUIQIDUIWOMENBIANCHENGYOUSHENMEQISHI?BENWENJIANGJIANDANLIYILIZIJIEDUIQIDENEIXIESHI。

什么是字節對齊

江苏快三开奖结果JISUANJIZHONGNEICUNDAXIAODEJIBENDANWEISHIZIJIE(byte),LILUNSHANGLAIJIANG,KEYICONGRENYIDIZHIFANGWENMOUZHONGJIBENSHUJULEIXING,DANSHISHIJISHANG,JISUANJIBINGFEIZHUZIJIEDAXIAODUXIENEICUN,ERSHIYI2,4,HUO8DE BEISHUDEZIJIEKUAILAIDUXIENEICUN,RUCIYILAIJIUHUIDUIJIBENSHUJULEIXINGDEHEFADIZHIZUOCHUYIXIEXIANZHI,JITADEDIZHIBIXUSHI2,4HUO8DEBEISHU。NEIMEJIUYAOQIUGEZHONGSHUJULEIXINGANZHAOYIDINGDEGUIZEZAIKONGJIANSHANGPAILIE,ZHEJIUSHIDUIQI。

對齊準則是什么

江苏快三开奖结果ZONGDELAISHUO,ZIJIEDUIQIYOUYIXIAZHUNZE:

  • 結構體變量的首地址能夠被其對齊字節數大小所整除
  • 結構體每個成員相對結構體首地址的偏移都是成員大小的整數倍,如不滿足,對前一個成員填充字節以滿足。
  • 結構體的總大小為結構體對齊字節數大小的整數倍,如不滿足,最后填充字節以滿足。

我們通過一個小例子來說明是如何對齊的。
考慮下面的程序

/*================================================================ *   Copyright (C) 2018  Ltd. All rights reserved. *    *   文件名稱:testByteAlign.c *   創 建 者:shouwang *   創建日期:2018年09月15日 *   描    述: * ================================================================*/ #include<stdio.h> #include<stdint.h> struct test {     int a;     char b;     int c;     short d; }; int main(int argc,char *argv) {     /*在32位和64位的機器上,size_t的大小不同*/     printf("the size of struct test is %zu\n",sizeof(struct test));     return 0; } 

江苏快三开奖结果BIANYICHENG32WEICHENGXUBINGYUNXING(MORENSIZIJIEZIRANDUIQI),KEYIKANDAO,JIEGOUTItest DEDAXIAOWEI16ZIJIE,ERBUSHI11ZIJIE(aZHAN4ZIJIE,bZHAN1ZIJIE,cZHAN4ZIJIE,dZHAN2ZIJIE)

#64位機器上編譯32位程序可能需要安裝一個庫 #sudo apt-get install gcc-multilib gcc -m32 -o testByteAlign testByteAlign.c #編譯程序 chmod +x testByteAlign  #賦執行權限 ./testByteAlign  #運行 the size of struct test is 16 

實際上,結構體test的成員在內存中可能是像下面這樣分布的(數值為偏移量)
未對齊時:

江苏快三开奖结果0~345~910~11abcd

DUIQISHI:

0~345~78~1112~1314~15abTIANCHONGNEIRONGcdTIANCHONGNEIRONG

從上面可以看出,c的偏移為5,不滿足對齊要求(它的偏移量應該能夠被sizeof(int)大小整除),因此在b后面填充了3個字節,使得c的偏移為8。在b后面填充后,d已經滿足對齊要求了,為什么最后還要填充字節呢?或者說,為什么需要滿足第三條準則呢?
考慮下面的聲明

struct teArray[2]; 

江苏快三开奖结果WOMENBUNANZHIDAO,teArray[0]DEdRUGUOBUTIANCHONGZIJIE,NEIMEteArray[1]DEaPIANYIWEI14,BUMANZUDUIQIYAOQIU,YINCIdHOUMIANYEXUYAOTIANCHONGZIJIE。

為什么要字節對齊

無論數據是否對齊,大多數計算機還是能夠正確工作,而且從前面可以看到,結構體test本來只需要11字節的空間,最后卻占用了16字節,很明顯浪費了空間,那么為什么還要進行字節對齊呢?最重要的考慮是提高內存系統性能
前面我們也說到,計算機每次讀寫一個字節塊,例如,假設計算機總是從內存中取8個字節,如果一個double數據的地址對齊成8的倍數,那么一個內存操作就可以讀或者寫,但是如果這個double數據的地址沒有對齊,數據就可能被放在兩個8字節塊中,那么我們可能需要執行兩次內存訪問,才能讀寫完成。顯然在這樣的情況下,是低效的。所以需要字節對齊來提高內存系統性能。
江苏快三开奖结果在有些處理器中,如果需要未對齊的數據,可能不能夠正確工作甚至crash,這里我們不多討論。

實際編程中的考慮

江苏快三开奖结果SHIJISHANG,ZIJIEDUIQIDEXIJIEDOUYOUBIANYIQILAIWANCHENG,WOMENBUXUYAOTEYIJINXINGZIJIEDEDUIQI,DANBINGBUYIWEIZHUWOMENBUXUYAOGUANZHUZIJIEDUIQIDEWENTI。

空間存儲

還是考慮前面的結構體test,其占用空間大小為16字節,但是如果我們換一種聲明方式,調整變量的順序,重新運行程序,最后發現結構體test占用大小為12字節

struct test {     int a;     char b;     short d;     int c; }; 

KONGJIANCUNCHUQINGKUANGRUXIA,bHEcCUNCHUZAILEYIGEZIJIEKUAIZHONG:

江苏快三开奖结果0~3456~78~11abTIANCHONGNEIRONGcd

江苏快三开奖结果YEJIUSHISHUO,RUGUOWOMENZAISHEJIJIEGOUDESHIHOU,HELIDIAOZHENGCHENGYUANDEWEIZHI,KEYIDADAJIESHENGCUNCHUKONGJIAN。

跨平臺通信

江苏快三开奖结果YOUYUBUTONGPINGTAIDUIQIFANGSHIKENENGBUTONG,RUCIYILAI,TONGYANGDEJIEGOUZAIBUTONGDEPINGTAIQIDAXIAOKENENGBUTONG,ZAIWUYISHIDEQINGKUANGXIA,HUXIANGFASONGDESHUJUKENENGCHUXIANCUOLUAN,SHENZHIYINFAYANZHONGDEWENTI。YINCI,WEILEBUTONGCHULIQIZHIJIANNENGGOUZHENGQUEDECHULIXIAOXI,WOMENYOULIANGZHONGKEXUANDECHULIFANGFA。

  • 1字節對齊
  • 自己對結構進行字節填充

我們可以使用偽指令#pragma pack(n)(n為字節對齊數)來使得結構間一字節對齊。
江苏快三开奖结果同樣是前面的程序,如果在結構體test的前面加上偽指令,即如下:

#pragma pack(1) /*1字節對齊*/ struct test {     int a;     char b;     int c;     short d; }; #pragma pack()/*還原默認對齊*/ 

ZAIZHEYANGDESHENGMINGXIA,RENHEPINGTAIJIEGOUTItestDEDAXIAODOUWEI11ZIJIE,ZHEYANGZUONENGGOUBAOZHENGKUAPINGTAIDEJIEGOUDAXIAOYIZHI,TONGSHIHUANJIESHENGLEKONGJIAN,DANBUXINGDESHI,JIANGDILEXIAOLV。

江苏快三开奖结果DANGRANLEDUIYUDANGEJIEGOUTI,gccHUANYOURUXIADEFANGFA,SHIQI1ZIJIEDUIQI

struct test {     int a;     char b;     int c;     short d; }__attribute__ ((packed)); 

ZHU:

  • __attribute__((aligned (n))),讓所作用的結構成員對齊在n字節自然邊界上。如果結構中有成員的長度大于n,則按照最大成員的長度來對齊。
  • __attribute__ ((packed)),取消結構在編譯過程中的優化對齊,也可以認為是1字節對齊。

江苏快三开奖结果CHULEQIANMIANDE1ZIJIEDUIQI,HUANKEYIJINXINGRENWEIDETIANCHONG,JItestJIEGOUTISHENGMINGRUXIA:

struct test {     int a;     char b;     char reserve[3];     int c;     short d;     char reserve1[2]; }; 

FANGWENXIAOLVGAO,DANBINGBUJIESHENGKONGJIAN,TONGSHIKUOZHANXINGBUSHIHENHAO,LIRU,DANGZIJIEDUIQIYOUBIANHUASHI,XUYAOTIANCHONGDEZIJIESHUKENENGJIUHUIFASHENGBIANHUA。

總結

江苏快三开奖结果SUIRANWOMENBUXUYAOJUTIGUANXINZIJIEDUIQIDEXIJIE,DANSHIRUGUOBUGUANZHUZIJIEDUIQIDEWENTI,KENENGHUIZAIBIANCHENGZHONGYUDAONANYILIJIEHUOJIEJUEDEWENTI。YINCIZHENDUIZIJIEDUIQI,ZONGJIELEYIXIACHULIJIANYI:

  • 結構體成員合理安排位置,以節省空間
  • 跨平臺數據結構可考慮1字節對齊,節省空間但影響訪問效率
  • 跨平臺數據結構人為進行字節填充,提高訪問效率但不節省空間
  • 本地數據采用默認對齊,以提高訪問效率
posted @ 2020-01-09 16:54 長戟十三千 閱讀(19) | 評論 (0)編輯 收藏
Linux 的虛擬內存管理有幾個關鍵概念: 
1、每個進程都有獨立的虛擬地址空間,進程訪問的虛擬地址并不是真正的物理地址; 
2、虛擬地址可通過每個進程上的頁表(在每個進程的內核虛擬地址空間)與物理地址進行映射,獲得真正物理地址; 
3、如果虛擬地址對應物理地址不在物理內存中,則產生缺頁中斷,真正分配物理地址,同時更新進程的頁表;如果此時物理內存已耗盡,則根據內存替換算法淘汰部分頁面至物理磁盤中。 
   
基于以上認識,進行了如下分析:
一、Linux 虛擬地址空間如何分布?
Linux 使用虛擬地址空間,大大增加了進程的尋址空間,由低地址到高地址分別為: 
1、只讀段:該部分空間只能讀,不可寫;(包括:代碼段、rodata 段(C常量字符串和#define定義的常量) )
2、數據段:保存全局變量、靜態變量的空間; 
3、堆 :就是平時所說的動態內存, malloc/new 大部分都來源于此。其中堆頂的位置可通過函數 brk 和 sbrk 進行動態調整。 
4、文件映射區域 :如動態庫、共享內存等映射物理空間的內存,一般是 mmap 函數所分配的虛擬地址空間。 
5、棧:用于維護函數調用的上下文空間,一般為 8M ,可通過 ulimit –s 查看。 
6、內核虛擬空間:用戶代碼不可見的內存區域,由內核管理(頁表就存放在內核虛擬空間)。
下圖是 32 位系統典型的虛擬地址空間分布(來自《深入理解計算機系統》)。
32 位系統有4G 的地址空間::
      其中 0x08048000~0xbfffffff 是用戶空間,0xc0000000~0xffffffff 是內核空間,包括內核代碼和數據、與進程相關的數據結構(如頁表、內核棧)等。另外,%esp 執行棧頂,往低地址方向變化;brk/sbrk 函數控制堆頂_edata往高地址方向變化。
64位系統結果怎樣呢? 64 位系統是否擁有 2^64 的地址空間嗎? 
事實上, 64 位系統的虛擬地址空間劃分發生了改變: 
1、地址空間大小不是2^32,也不是2^64,而一般是2^48。因為并不需要 2^64 這么大的尋址空間,過大空間只會導致資源的浪費。64位Linux一般使用48位來表示虛擬地址空間,40位表示物理地址,
這可通過 /proc/cpuinfo 來查看 
address sizes   : 40 bits physical, 48 bits virtual 
2、其中,0x0000000000000000~0x00007fffffffffff 表示用戶空間, 0xFFFF800000000000~ 0xFFFFFFFFFFFFFFFF 表示內核空間,共提供 256TB(2^48) 的尋址空間。
這兩個區間的特點是,第 47 位與 48~63 位相同,若這些位為 0 表示用戶空間,否則表示內核空間。 
3、用戶空間由低地址到高地址仍然是只讀段、數據段、堆、文件映射區域和棧;
 
二、malloc和free是如何分配和釋放內存?
如何查看進程發生缺頁中斷的次數?
         用ps -o majflt,minflt -C program命令查看。
          majflt代表major fault,中文名叫大錯誤,minflt代表minor fault,中文名叫小錯誤。
          這兩個數值表示一個進程自啟動以來所發生的缺頁中斷的次數。
發成缺頁中斷后,執行了那些操作?
當一個進程發生缺頁中斷的時候,進程會陷入內核態,執行以下操作: 
1、檢查要訪問的虛擬地址是否合法 
2、查找/分配一個物理頁 
3、填充物理頁內容(讀取磁盤,或者直接置0,或者啥也不干) 
4、建立映射關系(虛擬地址到物理地址) 
重新執行發生缺頁中斷的那條指令 
如果第3步,需要讀取磁盤,那么這次缺頁中斷就是majflt,否則就是minflt。 
內存分配的原理
從操作系統角度來看,進程分配內存有兩種方式,分別由兩個系統調用完成:brk和mmap(不考慮共享內存)。
1、brk是將數據段(.data)的最高地址指針_edata往高地址推;
2、mmap是在進程的虛擬地址空間中(堆和棧中間,稱為文件映射區域的地方)找一塊空閑的虛擬內存。
     這兩種方式分配的都是虛擬內存,沒有分配物理內存。在第一次訪問已分配的虛擬地址空間的時候,發生缺頁中斷,操作系統負責分配物理內存,然后建立虛擬內存和物理內存之間的映射關系。
在標準C庫中,提供了malloc/free函數分配釋放內存,這兩個函數底層是由brk,mmap,munmap這些系統調用實現的。
下面以一個例子來說明內存分配的原理:
情況一、malloc小于128k的內存,使用brk分配內存,將_edata往高地址推(只分配虛擬空間,不對應物理內存(因此沒有初始化),第一次讀/寫數據時,引起內核缺頁中斷,內核才分配對應的物理內存,然后虛擬地址空間建立映射關系),如下圖:
1、進程啟動的時候,其(虛擬)內存空間的初始布局如圖1所示。
      其中,mmap內存映射文件是在堆和棧的中間(例如libc-2.2.93.so,其它數據文件等),為了簡單起見,省略了內存映射文件。
      _edata指針(glibc里面定義)指向數據段的最高地址。 
2、進程調用A=malloc(30K)以后,內存空間如圖2:
      malloc函數會調用brk系統調用,將_edata指針往高地址推30K,就完成虛擬內存分配。
      你可能會問:只要把_edata+30K就完成內存分配了?
      事實是這樣的,_edata+30K只是完成虛擬地址的分配,A這塊內存現在還是沒有物理頁與之對應的,等到進程第一次讀寫A這塊內存的時候,發生缺頁中斷,這個時候,內核才分配A這塊內存對應的物理頁。也就是說,如果用malloc分配了A這塊內容,然后從來不訪問它,那么,A對應的物理頁是不會被分配的。 
3、進程調用B=malloc(40K)以后,內存空間如圖3。
情況二、malloc大于128k的內存,使用mmap分配內存,在堆和棧之間找一塊空閑內存分配(對應獨立內存,而且初始化為0),如下圖:
4、進程調用C=malloc(200K)以后,內存空間如圖4:
      默認情況下,malloc函數分配內存,如果請求內存大于128K(可由M_MMAP_THRESHOLD選項調節),那就不是去推_edata指針了,而是利用mmap系統調用,從堆和棧的中間分配一塊虛擬內存。
      這樣子做主要是因為::
      brk分配的內存需要等到高地址內存釋放以后才能釋放(例如,在B釋放之前,A是不可能釋放的,這就是內存碎片產生的原因,什么時候緊縮看下面),而mmap分配的內存可以單獨釋放。
      當然,還有其它的好處,也有壞處,再具體下去,有興趣的同學可以去看glibc里面malloc的代碼了。 
5、進程調用D=malloc(100K)以后,內存空間如圖5;
6、進程調用free(C)以后,C對應的虛擬內存和物理內存一起釋放。
7、進程調用free(B)以后,如圖7所示:
        B對應的虛擬內存和物理內存都沒有釋放,因為只有一個_edata指針,如果往回推,那么D這塊內存怎么辦呢?
當然,B這塊內存,是可以重用的,如果這個時候再來一個40K的請求,那么malloc很可能就把B這塊內存返回回去了。 
8、進程調用free(D)以后,如圖8所示:
        B和D連接起來,變成一塊140K的空閑內存。
9、默認情況下:
       當最高地址空間的空閑內存超過128K(可由M_TRIM_THRESHOLD選項調節)時,執行內存緊縮操作(trim)。在上一個步驟free的時候,發現最高地址空閑內存超過128K,于是內存緊縮,變成圖9所示。
三、既然堆內內存brk和sbrk不能直接釋放,為什么不全部使用 mmap 來分配,munmap直接釋放呢? 
        既然堆內碎片不能直接釋放,導致疑似“內存泄露”問題,為什么 malloc 不全部使用 mmap 來實現呢(mmap分配的內存可以會通過 munmap 進行 free ,實現真正釋放)?而是僅僅對于大于 128k 的大塊內存才使用 mmap ? 
        其實,進程向 OS 申請和釋放地址空間的接口 sbrk/mmap/munmap 都是系統調用,頻繁調用系統調用都比較消耗系統資源的。并且, mmap 申請的內存被 munmap 后,重新申請會產生更多的缺頁中斷。例如使用 mmap 分配 1M 空間,第一次調用產生了大量缺頁中斷 (1M/4K 次 ) ,當munmap 后再次分配 1M 空間,會再次產生大量缺頁中斷。缺頁中斷是內核行為,會導致內核態CPU消耗較大。另外,如果使用 mmap 分配小內存,會導致地址空間的分片更多,內核的管理負擔更大。
        同時堆是一個連續空間,并且堆內碎片由于沒有歸還 OS ,如果可重用碎片,再次訪問該內存很可能不需產生任何系統調用和缺頁中斷,這將大大降低 CPU 的消耗。 因此, glibc 的 malloc 實現中,充分考慮了 sbrk 和 mmap 行為上的差異及優缺點,默認分配大塊內存 (128k) 才使用 mmap 獲得地址空間,也可通過 mallopt(M_MMAP_THRESHOLD, <SIZE>) 來修改這個臨界值。
 
四、如何查看進程的缺頁中斷信息? 
可通過以下命令查看缺頁中斷信息 
ps -o majflt,minflt -C <program_name> 
ps -o majflt,minflt -p <pid> 
其中:: majflt 代表 major fault ,指大錯誤;
           minflt 代表 minor fault ,指小錯誤。
這兩個數值表示一個進程自啟動以來所發生的缺頁中斷的次數。
其中 majflt 與 minflt 的不同是::
        majflt 表示需要讀寫磁盤,可能是內存對應頁面在磁盤中需要load 到物理內存中,也可能是此時物理內存不足,需要淘汰部分物理頁面至磁盤中。
五、C語言的內存分配方式與malloc
  
C語言跟內存分配方式
(1) 從靜態存儲區域分配。內存在程序編譯的時候就已經分配好,這塊內存在程序的整個運行期間都存在。例如全局變量,static變量。
(2) 在棧上創建。在執行函數時,函數內局部變量的存儲單元都可以在棧上創建,函數執行結束時這些存儲單元自動被釋放。棧內存分配運
算內置于處理器的指令集中,效率很高,但是分配的內存容量有限。
(3)從堆上分配,亦稱動態內存分配。程序在運行的時候用malloc或new申請任意多少的內存,程序員自己負責在何時用free或delete釋放內存。動態內存的生存期由我們決定,使用非常靈活,但問題也最多
     
      C語言跟內存申請相關的函數主要有 alloc,calloc,malloc,free,realloc,sbrk等.其中alloc是向棧申請內存,因此無需釋放. malloc分配的內存是位于堆中的,并且沒有初始化內存的內容,因此基本上malloc之后,調用函數memset來初始化這部分的內存空間.calloc則將初始化這部分的內存,設置為0. 而realloc則對malloc申請的內存進行大小的調整.申請的內存最終需要通過函數free來釋放. 而sbrk則是增加數據段的大小;
       malloc/calloc/free基本上都是C函數庫實現的,跟OS無關.C函數庫內部通過一定的結構來保存當前有多少可用內存.如果程序 malloc的大小超出了庫里所留存的空間,那么將首先調用brk系統調用來增加可用空間,然后再分配空間.free時,釋放的內存并不立即返回給os, 而是保留在內部結構中. 可以打個比方: brk類似于批發,一次性的向OS申請大的內存,而malloc等函數則類似于零售,滿足程序運行時的要求.這套機制類似于緩沖.
使用這套機制的原因: 系統調用不能支持任意大小的內存分配(有的系統調用只支持固定大小以及其倍數的內存申請,這樣的話,對于小內存的分配會造成浪費; 系統調用申請內存代價昂貴,涉及到用戶態和核心態的轉換.
函數malloc()和calloc()都可以用來分配動態內存空間,但兩者稍有區別。
      在Linux系統上,程序被載入內存時,內核為用戶進程地址空間建立了代碼段、數據段和堆棧段,在數據段與堆棧段之間的空閑區域用于動態內存分配。
      內核數據結構mm_struct中的成員變量start_code和end_code是進程代碼段的起始和終止地址,start_data和 end_data是進程數據段的起始和終止地址,start_stack是進程堆棧段起始地址,start_brk是進程動態內存分配起始地址(堆的起始 地址),還有一個 brk(堆的當前最后地址),就是動態內存分配當前的終止地址。
C語言的動態內存分配基本函數是malloc(),在Linux上的基本實現是通過內核的brk系統調用。brk()是一個非常簡單的系統調用,只是簡單地改變mm_struct結構的成員變量brk的值。
      mmap系統調用實現了更有用的動態內存分配功能,可以將一個磁盤文件的全部或部分內容映射到用戶空間中,進程讀寫文件的操作變成了讀寫內存的操作。在 linux/mm/mmap.c文件的do_mmap_pgoff()函數,是mmap系統調用實現的核心。do_mmap_pgoff()的代碼,只是新建了一個vm_area_struct結構,并把file結構的參數賦值給其成員變量m_file,并沒有把文件內容實際裝入內存。
Linux內存管理的基本思想之一,是只有在真正訪問一個地址的時候才建立這個地址的物理映射。
————————————————
版權聲明:本文為CSDN博主「gfgdsg」的原創文章,遵循 CC 4.0 BY-SA 版權協議,轉載請附上原文出處鏈接及本聲明。
原文鏈接:http://blog.csdn.net/gfgdsg/article/details/42709943
posted @ 2019-12-25 15:36 長戟十三千 閱讀(12) | 評論 (0)編輯 收藏
     摘要: brk() , sbrk() 的聲明如下:#include <unistd.h>int brk(void *addr);void *sbrk(intptr_t increment);這兩個函數都用來改變 "program break" (程序間斷點)的位置,這個位置可參考下圖:如 man 里說的:引用brk()  and  sbrk() chan...  閱讀全文
posted @ 2019-12-25 15:25 長戟十三千 閱讀(12) | 評論 (0)編輯 收藏

ZAIwindowsPINGTAI,YOUYIGEJIANDANDEFANGFALAIZHUIZONGDIAOYONGHANSHUDEDUIZHAN,JIUSHILIYONGHANSHUCaptureStackBackTrace,DANSHIZHEGEHANSHUBUNENGDEDAOJUTIDIAOYONGHANSHUDEMINGCHENG,ZHINENGDEDAODIZHI,DANGRANWOMENKEYITONGGUOFANHUIBIANDEFANGSHITONGGUODIZHIDEDAOHANSHUDEMINGCHENG,YIJIJUTIDIAOYONGDEFANHUIBIANDAIMA,DANSHIDUIYUYOUDESHIHOUWOMENXUYAOZHIJIEDEDAOHANSHUDEMINGCHENG,ZHEGESHIHOUJUBUNENGSHIYONGZHEGEFANGFA,DUIYUZHEZHONGXUQIUWOMENKEYISHIYONGHANSHU:SymInitialize、StackWalk、SymGetSymFromAddr、SymGetLineFromAddr、SymCleanup。

原理

JIBENSHANGSUOYOUGAOJIYUYANDOUYOUZHUANMENWEIHANSHUZHUNBEIDEDUIZHAN,YONGLAICUNCHUHANSHUZHONGDINGYIDEBIANLIANG,ZAIC/C++ZHONGZAIDIAOYONGHANSHUZHIQIANHUIBAOCUNDANGQIANHANSHUDEXIANGGUANHUANJING,ZAIDIAOYONGHANSHUSHISHOUXIANJINXINGCANSHUYAZHAN,RANHOUcallZHILINGJIANGDANGQIANeipDEZHIYARUDUIZHANZHONG,RANHOUDIAOYONGHANSHU,HANSHUSHOUXIANHUIJIANGZISHENDUIZHANDEZHANDIDIZHIBAOCUNZAIebpZHONG,RANHOUTAIGAOespBINGCHUSHIHUABENSHENDEDUIZHAN,TONGGUODUOCIDIAOYONGZUIZHONGZAIDUIZHANDUANXINGCHENGZHEYANGDEBUJU

江苏快三开奖结果 ZHELIDUIHANSHUDEYUANLIZUOJIANDANDEJIESHAO,YOUXINGQUDEKEYIKANWODELINGYIPIANGUANYUCHANSHUYUANLIJIANGJIEDEBOKE, VC++BIANYIQIZAIBIANYISHIDUIHANSHUMINGCHENGYUDIZHIDOUYOUXIANGXIDEJILU,BIANYICHULAIDECHENGXUDOUYOUYIGEFUHAOCHANGLIANGBIAO,JIANGFUHAOCHANGLIANGYUTADUIYINGDEDIZHIXINGCHENGYINGSHE,ZAISOUSUOSHISHOUXIANGENJUZHEXIEDUIZHANHUANJINGZHAODAODUIYINGDIZHI,RANHOUGENJUDIZHIZAIFUHAOCHANGLIANGBIAOZHONG,ZHAODAOJUTIDIAOYONGDEXINXI,ZHESHIYIGEHENFUZADEGONGCHENG,XUYAODUIBIANYIYUANLIHEHUIBIANYOUHENQIANGDEJICHU,XINGYUNDESHI,RUJINZHEXIEGONGZUOBUXUYAOCHENGXUYUANZIJIQUZUO,windowsBANGZHUWOMENFENPEILEYIZUAPI,ZAIBIANXIECHENGXUSHIZHIXUYAODIAOYONGAPIJIKE

函數說明

SymInitialize:ZHEGEHANSHUZHUYAOYONGZUOCHUSHIHUAXIANGGUANHUANJING。 SymCleanup:QINGCHUZHEGECHUSHIHUADEXIANGGUANHUANJING,ZAIDIAOYONGSymInitializeZHIHOUXUYAODIAOYONGSymCleanup,JINXINGSHIFANGZIYUANDECAOZUO StackWalk:CHENGXUDEGONGNENGZHUYAOYOUZHEGEHANSHUSHIXIAN,HANSHUHUICONGCHUSHIHUASHIDEDUIZHANDINGKAISHIXIANGXIACHAZHAOXIAYIGEDUIZHANDEXINXI,YUANXINGRUXIA:

BOOL WINAPI StackWalk(   __in          DWORD MachineType, //機器類型現在一般是intel的x86系列,這個時候填入IMAGE_FILE_MACHINE_I386   __in          HANDLE hProcess, //追蹤的進程句柄   __in          HANDLE hThread, //追蹤的線程句柄   __in_out      LPSTACKFRAME StackFrame, //記錄的追蹤到的堆棧信息   __in_out      PVOID ContextRecord, //記錄當前的線程環境   __in          PREAD_PROCESS_MEMORY_ROUTINE ReadMemoryRoutine,   __in          PFUNCTION_TABLE_ACCESS_ROUTINE FunctionTableAccessRoutine,   __in          PGET_MODULE_BASE_ROUTINE GetModuleBaseRoutine,   __in          PTRANSLATE_ADDRESS_ROUTINE TranslateAddress //后面的四個參數都是回掉函數,有系統自行調用,而且這些函數都是定義好的,只需要填入相應的函數名稱 );

XUYAOZHUYIDEYIDIANSHI,ZAISHOUCIDIAOYONGGAIHANSHUSHIXUYAODUIStackFrameZHONGDEAddrPC、AddrFrame、AddrStackZHESANGECHENGYUANJINXINGCHUSHIHUA,TIANRUXIANGGUANZHI,YIBIANHANSHUCONGCICHUXIANCHENGDUIZHANDEZHANDINGJINXINGSOUSUO,FOUZEDIAOYONGHANSHUJIANGSHIBAI,JUTIRUHETIANXIEQINGKANMSDN。

SymGetSymFromAddr:根據獲取到的函數地址得到函數名稱、堆棧大小等信息,這個函數的原型如下: BOOL WINAPI SymGetSymFromAddr(   __in          HANDLE hProcess, //進程句柄   __in          DWORD Address, //函數地址   __out         PDWORD Displacement, //返回該符號常量的位移或者填入NULL,不獲取此值   __out         PIMAGEHLP_SYMBOL Symbol//返回堆棧信息 );

SymGetLineFromAddr:GENJUDEDAODEDIZHIZHI,HUOQUDIAOYONGHANSHUDEXIANGGUANXINXI。ZHUYAOJILUSHIZAINAGEWENJIAN,NAXINGDIAOYONGLEGAIHANSHU,XIAMIANSHIHANSHUYUANXING:

BOOL WINAPI SymGetLineFromAddr(   __in          HANDLE hProcess,   __in          DWORD dwAddr,   __out         PDWORD pdwDisplacement,   __out         PIMAGEHLP_LINE Line );

TACANSHUDEHANYIYUSymGetSymFromAddr,XIANGTONG。 TONGGUOSHANGMIANDUIHANSHUDESHUOMING,WOMENKEYIZHIDAO,WEILEZHUIZONGHANSHUDIAOYONGDEXIANGXIXINXI,DAZHIBUZOURUXIA: 1. SHOUXIANDIAOYONGHANSHUSymInitializeJINXINGXIANGGUANDECHUSHIHUAGONGZUO。 2. TIANCHONGJIEGOUTIStackFrameDEXIANGGUANXINXI,QUEDINGCONGHECHUKAISHIZHUIZONG。 3. XUNHUANDIAOYONGStackWalkHANSHU,CONGZHIDINGWEIZHI,XIANGXIAYIZHIZHUIZONGDAOZUIHOU。 4. MEICIJIANGHUOQUDEDIZHIFENBIECHUANRUSymGetSymFromAddr、SymGetLineFromAddr,DEDAOHANSHUDEXIANGXIXINXI 5. DIAOYONGSymCleanup,JIESHUZHUIZONG DANSHIXUYAOZHUYIDEYIDIANSHI,HANSHUStackWalkHUISHUNZHUXIANCHENGDUIZHANJINXINGCHAZHAO,RUGUOZAIDIAOYONGZHIQIAN,MOUGEHANSHUYIJINGFANHUILE,TADEDUIZHANBEIHUISHOU,NEIMEHANSHUStackWalkZIRANBUHUIZHUIZONGDAOGAIHANSHUDEDIAOYONG。

具體實現

void InitTrack() {     g_hHandle = GetCurrentProcess();      SymInitialize(g_hHandle, NULL, TRUE); }  void StackTrack() {     g_hThread = GetCurrentThread();     STACKFRAME sf = { 0 };      sf.AddrPC.Offset = g_context.Eip;     sf.AddrPC.Mode = AddrModeFlat;      sf.AddrFrame.Offset = g_context.Ebp;     sf.AddrFrame.Mode = AddrModeFlat;      sf.AddrStack.Offset = g_context.Esp;     sf.AddrStack.Mode = AddrModeFlat;      typedef struct tag_SYMBOL_INFO     {         IMAGEHLP_SYMBOL symInfo;         TCHAR szBuffer[MAX_PATH];     } SYMBOL_INFO, *LPSYMBOL_INFO;      DWORD dwDisplament = 0;     SYMBOL_INFO stack_info = { 0 };     PIMAGEHLP_SYMBOL pSym = (PIMAGEHLP_SYMBOL)&stack_info;     pSym->SizeOfStruct = sizeof(IMAGEHLP_SYMBOL);     pSym->MaxNameLength = sizeof(SYMBOL_INFO) - offsetof(SYMBOL_INFO, symInfo.Name);     IMAGEHLP_LINE ImageLine = { 0 };     ImageLine.SizeOfStruct = sizeof(IMAGEHLP_LINE);      while (StackWalk(IMAGE_FILE_MACHINE_I386, g_hHandle, g_hThread, &sf, &g_context, NULL, SymFunctionTableAccess, SymGetModuleBase, NULL))     {         SymGetSymFromAddr(g_hHandle, sf.AddrPC.Offset, &dwDisplament, pSym);         SymGetLineFromAddr(g_hHandle, sf.AddrPC.Offset, &dwDisplament, &ImageLine);         printf("當前調用函數 : %08x+%s(FILE[%s]LINE[%d])\n", pSym->Address, pSym->Name, ImageLine.FileName, ImageLine.LineNumber);     }  }  void UninitTrack() {     SymCleanup(g_hHandle); }

CESHICHENGXURUXIA:

void func1() {     OPEN_STACK_TRACK; }  void func2() {     func1(); }  void func3() {     func2();  } void func4() {     printf("hello\n"); }  int _tmain(int argc, TCHAR* argv[]) {     func4();     func3();     func3();     return 0; }

OPEN_STACK_TRACKSHIYIGEHONG,TADEDINGYIRUXIA:

#define OPEN_STACK_TRACK\  HANDLE hThread = GetCurrentThread();\ GetThreadContext(hThread, &g_context);\ __asm{call $ + 5}\ __asm{pop eax}\ __asm{mov g_context.Eip, eax}\ __asm{mov g_context.Ebp, ebp}\ __asm{mov g_context.Esp, esp}\ InitTrack();\ StackTrack();\ UninitTrack();

ZHEGECHENGXUXUYAOZHUYIYIXIAJIDIAN: 1. RUGUOXIANGYAOZHUIZONGSUOYOUDIAOYONGDEHANSHU,XUYAOJIANGZHEGEHONGFANGZHIDAOZUIHOUDIAOYONGDEWEIZHI,DANGRANQIANTISHICISHIZHIQIANBEIDIAOHANSHUDEDUIZHANRENGRANCUNZAI。DANGRANKEYIZAIDIAOYONGQIANJIANDANDEJISUAN,ZHAOCHUZAINAGEWEIZHISHISUOYOUHANSHUDOUMEIYOUDIAOYONGWANCHENGDE,BUGUOZHEYANGKENENGJIUYUCHENGXUDECHUZHONGXIANGBEI,BIJINGCHENGXUBENSHENJIUSHIWEILEHUOQUDUIZHANDEDIAOYONGXINXI。。。。 2. IMAGEHLP_SYMBOLDEJIEGOUTIZHONGGUANYUNameDECHENGYUAN,ZHIYOUYIGEZIJIE,ERHANSHUSymGetSymFromAddrZAITIANRUZHISHISHIMEIYOUGUANXINZHEGESHIJIDAXIAO,TAZHISHIJIANDANDETIANCHONG,ZHEJIUZAOCHENGLEHUANCHONGQUYICHUDEQINGKUANG,WEILEBIMIANWOMENXUYAOZAINameHOUMIANEWAIGEIYIDINGDAXIAODEHUANCHONGQU,YONGLAIJIESHOUSHUJU,ZHEYEJIUSHIWOMENDINGYIZHEGEJIEGOUTISYMBOL_INFODEYUANYIN。LINGWAIIMAGEHLP_SYMBOLZHONGDEMaxNameLengthCHENGYUANSHIZHINameDEZUIDACHANGDU,XUYAOGENJUGEIDINGDEHUANCHONGQU,JINXINGJISUAN。 3. CONGCESHICHENGXULAIKAN,ZAIJINXINGZHUIZONGSHIfunc4YIJINGDIAOYONGWANCHENG,ERWOMENZAIHUOQUXIANCHENGDEYUNXINGSHIHUANJINGg_contextSHIHANSHUGetThreadContext,YEZAIDUIZHANZHONG,ZUIZHONGDEDAODEJIEGUOZHONGBIRANBAOHANGetThreadContextDEDIAOYONGXINXI,RUGUOXIANGQUDIAOZHEGEXINXI,ZHIXUYAOXIUGAIHUODEXINXIDEZHI,JIRANHANSHUStackWalkSHIGENJUDUIZHANJINXINGZHUIZONG,NEIMEZHIXUYAOXIUGAIDUIYINGDUIZHANDEXINXIJIKE,XUYAOXIUGAIeip 、ebp、espDEZHI,GUANYUesp ebpDEZHIHENHAOXIUGAI,KEYIZAIDUIYINGHANSHUZHONGesp ebpZHEXIEJICUNQIDEZHI,EReipDEZHIJIUBUNEIMEHAOHUOQU,BENSHENGLIYONGmovZHILINGDEDAOeipDEZHITAYESHIZHILING,HUIGAIBIANeipDEZHI,CONGERZAOCHENGHUOQUDAODEeipDEZHIBUZHUNQUE,SUOYIWOMENLIYONGcallZHILING,XIANBAOCUNDANGQIANeipDEZHIDAODUIZHAN,RANHOUZAICONGDUIZHANZHONGQUCHU。callZHILINGDESHIZHISHI push eipHEjmp addrZHILINGDEZUHE,BINGBUYIDINGFEIYAODIAOYONGHANSHU。callZHILINGDEDAXIAOWEI5GEZIJIE,SUOYIcall $ + 5BIAOSHIXIANBAOCUNeipZAITIAOZHUANDAOTADEXIAYITIAOZHILINGCHU。ZHEYANGJIUKEYIYOUXIAODEBIMIANJIANCEDAOGetThreadContextZHONGDEXIANGGUANHANSHUDIAOYONG

posted @ 2019-12-19 12:39 長戟十三千 閱讀(18) | 評論 (0)編輯 收藏