c++實現(xiàn)reactor高并發(fā)服務(wù)器的詳細(xì)教程
環(huán)境準(zhǔn)備
- linux虛擬機
- 安裝升級c/c++編譯器
- gcc/g++ 選項 源代碼文件1 源代碼文件2 ... 源代碼文件n
- -o指定輸出的文件名(不能和源文件同名 默認(rèn)是a.out)
- -g調(diào)試 -On鏈接時優(yōu)化 減小體積(n=1-3) -c只編譯 用于生成庫
- -std=c++11 支持c++11標(biāo)準(zhǔn)
- 安裝man功能
- man 級別 接口/命令
- 級別: 1系統(tǒng)命令 2系統(tǒng)接口 3庫函數(shù) 4設(shè)備文件 5文件 9內(nèi)核
- 安裝vscode c/c++插件 簡體中文插件 Remote-ssh插件
基礎(chǔ)知識
靜態(tài)庫動態(tài)庫
g++ -c -o libxxx.a xxx.cpp
生成了libxxx.a的靜態(tài)庫
g++ -o demo demo.cpp -L/path/xxx -lxxx
-L指定路徑 -l指定靜態(tài)庫名- 用靜態(tài)庫和用源代碼是一樣的,好處是可以隱藏源代碼
g++ -fPIC -shared -o libxxx.so xxx.cpp
制作動態(tài)庫 調(diào)用方式同上
- 用動態(tài)庫必須先把目錄加到LD_LIBRARY_PATH
- 動態(tài)庫是編譯時不會連接到程序中,而是運行時裝入,如果多個程序用到同一靜態(tài)庫,只在內(nèi)存有一份(代碼共享),避免空間浪費
**靜態(tài)動態(tài)庫都有 優(yōu)先使用動態(tài)
makefile
每次編譯都要g++ xxxx很麻煩,果然懶惰是第一生產(chǎn)力
highlighter- livecodeserver
# 指定編譯的目標(biāo)文件是生成這倆庫 all:libxxx.a \ libxxx.so # 編譯libxxx.a時,如果發(fā)現(xiàn)后面這倆文件變化了 重新編譯 libxxx.a: main.h main.cpp g++ -c -o libxxx.a main.cpp+ # 同上 libxxx.so: main.h main.cpp g++ -fPIC -shared -o libxxx.so main.cpp # make clean命令 clean: rm -f libxxx.a libxxx.so
- 增量編譯,也就是說當(dāng)前目錄下有靜態(tài)/動態(tài)了,就不編譯這個了
- 用-I指定頭文件包含路徑
- g++前面是個tab,而不是八個空格
- main函數(shù)第三個是char* envp[] 打印出來效果如同env命令
- int setenv(const char* name, const char* value, int override) 環(huán)境變量名/值/是否替換 返回0成功-1失敗(幾乎不失敗) 只對當(dāng)前進(jìn)程生效 進(jìn)程終止下次就沒有了,對shell無效
gdb調(diào)試
yum -y install gdb
安裝- 編譯時加-g 不要加-On
- gdb常用命令
- set args xx xx xx 設(shè)置參數(shù)
- break/b xx 在第某行打斷點 (ctrl+g顯示行號 或者vi下:set number)
- run/r 一直運行直到斷點
指令 | 用處 | 其他說明 |
---|---|---|
set args xx xx | 設(shè)置參數(shù) | |
break/b 20 | 在第20行打斷點 | ctrl+g 或 :set number |
run/r | 從頭一直運行直到斷點 | |
next/n | 執(zhí)行當(dāng)前語句 | 若為函數(shù)調(diào)用不進(jìn)入 |
step/s | 執(zhí)行當(dāng)前語句 | 進(jìn)入(庫函數(shù)由于無源碼進(jìn)不去) |
continue/c | 運行到下一個斷點 | |
print/p xx | 查看變量/表達(dá)式的值 | 甚至可以p strlen(xx) p xx = 1 |
set var xx = xx | 調(diào)試時設(shè)置參數(shù) | |
quit/q | 退出gdb |
- 出現(xiàn)段錯誤時(操作空指針) 程序會被內(nèi)核強行終止,保存在core文件中(需要先ulimit -a 查看 core file size ulimit -c unlimited更改后才能看到)
gdb demo core.123
調(diào)試core文件 bt查看函數(shù)調(diào)用棧- ps -ef|grep demo 查看進(jìn)程號 gdb -p demo 123 會自動停止
linux
時間 <time.h>
- time_t
typedef long time_t
- 獲取1970/1/1到現(xiàn)在的秒數(shù)
time_t now = time(0)
time_t now; time(&now)
tm結(jié)構(gòu)體
從time_t轉(zhuǎn)tm結(jié)構(gòu)體,注意加_r 線程安全localtime_r(&now, &tmnow)
mktime(&tm)
把結(jié)構(gòu)體轉(zhuǎn)time_t
gettimeofday(struct timeinterval* tv, struct timezone* tz)
獲取1970/1/1到現(xiàn)在的秒數(shù)+當(dāng)前的微秒數(shù)
- sleep(秒) usleep(微秒)
目錄操作<unistd.h>
- 獲取當(dāng)前目錄
char* getcwd(char* buf, size_t size)
char* get_current_dir_name()
- 相當(dāng)于pwd,目錄最大長度255 getcwd需要初始化一個256長度的字符數(shù)組,get_current_dir_name需要接free
切換目錄
int chdir(const char*path)
創(chuàng)建目錄
int mkdir(const char*pathname, mode_t mode)
- mode如0755,不要省略0
- 刪除目錄
int rmdir(const char*path)
<dirent.h> 讀取目錄相當(dāng)于ls -a
highlighter- cpp
DIR* opendir(const char* path); //打開目錄 struct dirent*readdir(DIR* dirp); //讀取目錄 int closedir(DIR* dirp); //關(guān)閉目錄
- 其中 d_type = 8 是文件,= 4 是子目錄
a
- 判斷文件是否有某個權(quán)限,有返回0 沒有返回-1
int access(const char* path, int mode)
stat結(jié)構(gòu)體,有很多成員,比ls列出的還多int stat(const char*path, struct stat*buf)
修改目錄或文件的時間
int utime(const char* path,const struct utimbuf* time)
rename庫函數(shù) 相當(dāng)于mv
int rename(const char* old, const char* new)
remove庫函數(shù) 相當(dāng)于rm
int remove(const char* path)
Linux系統(tǒng)錯誤 <errno.h>
獲取錯誤代碼的詳細(xì)信息
char* strerror(int errnum)
int strerror_r(int errnum, char* buf, size_t buflen)
控制臺顯示最近一次系統(tǒng)錯誤的詳細(xì)信息
void perrpr(const char*s)
- 不是系統(tǒng)調(diào)用的函數(shù),不會設(shè)置errorno?。。?!
- 相當(dāng)于出現(xiàn)error時,printf打印一下,但是error不會自動清零,所以一般是判斷if (ret!=0) 也就是執(zhí)行失敗再去看錯誤
linux信號
可以用默認(rèn)的信號操作(通常會終止進(jìn)程) 也可以用signal函數(shù)自定義處理方式,但是有的信號不可被捕獲、忽略 如9
sighandler_t signal(int signum, sighandler_t func)
void (*sighandler_t)(int);
- 說明信號處理函數(shù)返回值void 入?yún)nt
- func傳入 SIG_IGN 表示忽略這個值的信號 SIG_DFL表示恢復(fù)默認(rèn)
- alarm(5); signal(14,func); 用于定時五秒發(fā)送鬧鐘信號(14)然后執(zhí)行func函數(shù)~~ 注意 func中需要有alarm(5) 不然就只會處理一次咯??!
進(jìn)程終止
- main函數(shù)中,return返回
- 任意函數(shù)調(diào)用exit, _exit() , Exit()
- exit()不會調(diào)用局部變量的析構(gòu),但是會調(diào)用全局變量的析構(gòu)
- _exit() 和 Exit() 直接退出,不會進(jìn)行任何操作
退出線程:pthread_exit() 線程主函數(shù)return
abort()異常終止、接收到信號、最后一個線程對取消請求做出響應(yīng)
終止的狀態(tài)就是main中 return 幾
- exit(5) 可以把狀態(tài)變成5 退出后,用echo $?查看
參考資料
- 環(huán)境準(zhǔn)備
- 基礎(chǔ)知識
- 靜態(tài)庫動態(tài)庫
- makefile
- gdb調(diào)試
- linux
- 時間
- 目錄操作
- Linux系統(tǒng)錯誤
- linux信號
- 進(jìn)程終止
到此這篇關(guān)于c++從零實現(xiàn)reactor高并發(fā)服務(wù)器的文章就介紹到這了,更多相關(guān)c++ reactor高并發(fā)服務(wù)器內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
C語言?超詳細(xì)梳理總結(jié)動態(tài)內(nèi)存管理
動態(tài)內(nèi)存是相對靜態(tài)內(nèi)存而言的。所謂動態(tài)和靜態(tài)就是指內(nèi)存的分配方式。動態(tài)內(nèi)存是指在堆上分配的內(nèi)存,而靜態(tài)內(nèi)存是指在棧上分配的內(nèi)存,本文帶你深入探究C語言中動態(tài)內(nèi)存的管理2022-03-03C語言結(jié)構(gòu)體嵌套與對齊超詳細(xì)講解
這篇文章主要介紹了C語言結(jié)構(gòu)體嵌套與對齊,C語言中結(jié)構(gòu)體是一種構(gòu)造類型,和數(shù)組、基本數(shù)據(jù)類型一樣,可以定義指向該種類型的指針。結(jié)構(gòu)體指針的定義類似其他基本數(shù)據(jù)類型的定義2022-12-12C語言數(shù)據(jù)結(jié)構(gòu)之判斷循環(huán)鏈表空與滿
這篇文章主要介紹了C語言數(shù)據(jù)結(jié)構(gòu)之判斷循環(huán)鏈表空與滿的相關(guān)資料,希望通過本文能幫助到大家,讓大家掌握這部分內(nèi)容,需要的朋友可以參考下2017-10-10