欧美1区2区3区激情无套,两个女人互添下身视频在线观看,久久av无码精品人妻系列,久久精品噜噜噜成人,末发育娇小性色xxxx

面試必問:六大高并發(fā)模型!

網(wǎng)絡(luò)編程是Linux C/C++的面試重點(diǎn),這次我就來聊聊進(jìn)程間通信和線程同步的問題,可以參看《unix高級環(huán)境編程》,希望幫助到大家。

值得一讀:
1、http://fangfengwang8.cn/discuss/193598?source_id=profile_create&channel=2002(Linux C/C++ 學(xué)習(xí)路線,已拿 BAT offer?。?
2、http://fangfengwang8.cn/discuss/225624?source_id=profile_create&channel=2002(我憑著這份簡歷,拿下了 BAT offer)
3、http://fangfengwang8.cn/discuss/439259?source_id=profile_create&channel=2002(“校招簡歷”應(yīng)該怎么寫)

關(guān)于如何寫簡歷,以及我的簡歷模板(好好看看上面推薦的文章),或者實(shí)習(xí)、秋招有什么問題,都可以私信找我,很愿意幫助到大家。

上次分享了進(jìn)程間通信和線程同步的問題,這次就來說說高并發(fā)的一些事情,這些都是網(wǎng)絡(luò)編程的重點(diǎn),也是面試常問的一些,我將自己整理的一些,分享給大家。


我在校期間走的是Linux C/C++方向,提供的都是Linux下面的編程模型,希望對需要的人有幫助

正文


六大高并發(fā)模型


多進(jìn)程、多線程、線程池、select、poll、epoll

1、多進(jìn)程并發(fā)編程


利用的是TCP協(xié)議

核心思想:一個(gè)服務(wù)器和客戶端進(jìn)行并發(fā)訪問,每個(gè)客戶端都有自己的套接字描述符,在connect()、send()、recv()時(shí)發(fā)送對應(yīng)的socket文件描述符(就知道是哪個(gè)客戶端跟服務(wù)器進(jìn)行通信,誰發(fā)的數(shù)據(jù),將數(shù)據(jù)發(fā)給誰就一清二楚);然后服務(wù)器給每一個(gè)客戶端都fork()一個(gè)子進(jìn)程,形成一對一的訪問機(jī)制;當(dāng)一個(gè)客戶端連接關(guān)閉時(shí),的退出當(dāng)前子進(jìn)程

缺點(diǎn):a、啟動(dòng)和關(guān)閉子進(jìn)程帶來很大的開銷;b、系統(tǒng)最多只能產(chǎn)生512個(gè)進(jìn)程,也就是說最多只有512個(gè)客戶,形成不了處理大型訪問的情形

多線程并發(fā)編程

利用的是TCP協(xié)議

每到來一個(gè)客戶端,就創(chuàng)建一個(gè)線程,通過其中的函數(shù)指針來處理業(yè)務(wù);通過connect()來進(jìn)行連接,發(fā)送其客戶端的套接字;是一對一的服務(wù);當(dāng)一個(gè)客戶端連接關(guān)閉時(shí),的退出當(dāng)前子線程

缺點(diǎn):多線程網(wǎng)絡(luò)服務(wù)也存在線程的動(dòng)態(tài)申請與釋放,還是有一定的開銷,若存在大量用戶在線,很可能帶來線程間切換開銷

2、線程池并發(fā)編程


針對多線程網(wǎng)絡(luò)服務(wù)模式的一些不足之處而提出的改進(jìn)模式

其基本理念是:先創(chuàng)建一批資源,當(dāng)有用戶到來時(shí),直接分配以創(chuàng)建好的資源,它的主要目的是減少系統(tǒng)在頻繁創(chuàng)建資源時(shí)的開銷

實(shí)現(xiàn)原理:主服務(wù)線程創(chuàng)建既定數(shù)量的服務(wù)線程,當(dāng)有客戶端到來時(shí),則從線程池中找出空閑的服務(wù)線程,為其服務(wù),服務(wù)完畢后,線程不進(jìn)行釋放,重新放回線程池;若當(dāng)前線程池已滿,則將當(dāng)前的客戶端加入等待隊(duì)列

3、怎么實(shí)現(xiàn)線程池


typedef?struct?PoolStruct{
int?sockConn;???//接收客戶端的套接字,通過accept()函數(shù)的返回;
THREAD_TAG?flag;???//連接的狀態(tài),此時(shí)的繁忙/空閑
}PoolStruct;

將空閑、繁忙狀態(tài)寫為枚舉類型;

typedef enum{IDEL, BUSY} THREAD_TAG;
在客戶端連接前,先創(chuàng)建一批線程資源

創(chuàng)建線程池?cái)?shù)組,首先遍歷一遍數(shù)組,將套接字初始化為:0,設(shè)置為:空閑狀態(tài)

每連接一個(gè)客戶端accept(),然后遍歷線程池?cái)?shù)組,找到空閑狀態(tài)的,將當(dāng)前客戶端的套接字賦值過去(目的:記錄當(dāng)前服務(wù)器是與哪個(gè)客戶端進(jìn)行通信),并且將當(dāng)前狀態(tài)置為繁忙;用該線程為用戶提供一對一的服務(wù)

線程結(jié)束后,將其不回收,在次放入線程池,將套接字設(shè)為0,狀態(tài)設(shè)為空閑,

若線程池中的線程都在繁忙,用戶進(jìn)入等待狀態(tài),將其用隊(duì)列(accept()函數(shù)的返回值,接收客戶端的套接字)存儲(chǔ)起來,先入先出,每當(dāng)下一個(gè)客戶端連接該服務(wù)器時(shí),調(diào)用該函數(shù),先看等待隊(duì)列中有沒有等待的用戶,有,直接加入等待隊(duì)列,沒有,都要遍歷一遍線程池?cái)?shù)組,看看何時(shí)有空閑的線程資源;此時(shí)有空閑資源,先分配給隊(duì)列中的用戶,隊(duì)列中沒有,則分配給該用戶

分析總結(jié):

(1)、其優(yōu)點(diǎn):性能高效

(2)、可能存在的問題:新用戶如果在等待隊(duì)列里耗時(shí)過長,會(huì)影響用戶體驗(yàn)

針對此問題,改進(jìn)方案如下:

a、動(dòng)態(tài)創(chuàng)建新的服務(wù)線程,服務(wù)結(jié)束后,該線程加入線程池,這種改進(jìn)的好處是,用戶體驗(yàn)得到提升,潛在問題是,在長時(shí)間,大規(guī)模的并發(fā)用戶狀態(tài)下,線程會(huì)產(chǎn)生很多,最終會(huì)因?yàn)橘Y源消耗過多,系統(tǒng)退出

b、增加一個(gè)線程資源回收機(jī)制,當(dāng)線程池的規(guī)模達(dá)到一定程度或滿足某種既定規(guī)則時(shí),會(huì)主動(dòng)殺死一些線程,以達(dá)到系統(tǒng)穩(wěn)定和用戶體驗(yàn)之間折中。

當(dāng)有客戶端來,有2種做法,i>、創(chuàng)建線程為其服務(wù);ii>、加入等待隊(duì)列;這2種都不太合適,采用折中法,有一個(gè)上限值,即就是規(guī)定一個(gè)創(chuàng)建線程的最大數(shù),當(dāng)來一個(gè)用戶,還沒達(dá)到線程最大數(shù)時(shí),為其創(chuàng)建線程,若達(dá)到了,則加入等待隊(duì)列

對線程資源的回收:i>、立馬回收,ii>、暫時(shí)不回收;當(dāng)空閑的線程數(shù)達(dá)到某一下限值時(shí),此時(shí)再將線程回收

Linux I/O多路復(fù)用,都是針對高并發(fā)的情況下,創(chuàng)建一個(gè)線程可以為多個(gè)客戶服務(wù)的一種模式;同一個(gè)時(shí)刻,只能為一個(gè)客戶服務(wù)(作用排隊(duì))

4、select()


select的調(diào)用在FD_ZERO()和FD_SET()之后調(diào)用

5、poll()


poll()的調(diào)用時(shí)機(jī)和select()一樣,在監(jiān)聽之后

6、epoll()


epoll的調(diào)用順序:socket---->bind----->listen----->epoll_create----->增加事件(epoll_ctl())>epoll_wait----->accept(建立連接)---->讀/寫(在讀寫中刪除和修改事件-->通過epoll_ctl())

分模塊的執(zhí)行每一塊代碼

epoll_create();創(chuàng)建一個(gè)文件描述符,來唯一的標(biāo)識內(nèi)核中創(chuàng)建的事件表(用戶關(guān)心的文件描述符就放在內(nèi)核事件表中)

epoll_ctl():往事件表上注冊/修改/刪除事件

epoll_wait():返回就緒的文件描述符的個(gè)數(shù),如果檢測到事件,就將所有就緒的事件從內(nèi)核事件表中復(fù)制到它的第二個(gè)參數(shù)events指向的數(shù)組中

該events數(shù)組只輸出檢測到的就緒事件

比較


1、epoll的工作模式:


LT(電平觸發(fā)):當(dāng)epoll_wait檢測到其上有事件發(fā)生并將此事件通知應(yīng)用程序后,應(yīng)用程序可以不立即處理該事件,這樣,當(dāng)下一次調(diào)用epoll_wait時(shí),還會(huì)再次向應(yīng)用程序告知此事件,直到該事件被處理

ET(邊沿觸發(fā)):當(dāng)epoll_wait檢測到其上有事件發(fā)生并將此事件通知應(yīng)用程序后,應(yīng)用程序必須立即處理該事件

所以:ET模式在很大程度上降低了同一個(gè)epoll事件被重復(fù)觸發(fā)的次數(shù),因此效率要比LT模式高

EPOLLONESHOT事件:針對使用ET模式還是可能被觸發(fā)多次,只有在epoll_ctl函數(shù)的文件描述符上注冊EPOLLONESHOT事件,此時(shí)只觸發(fā)一次

2、三組I/O復(fù)用函數(shù)的比較


都能同時(shí)監(jiān)聽多個(gè)文件描述符,直到一個(gè)或多個(gè)文件描述符上有事件發(fā)生時(shí)返回,返回值是就緒的文件描述符的數(shù)量

事件集:

select:參數(shù)fd_set,沒有將文件描述符和事件綁定;其僅僅是一個(gè)文件描述符集合

poll:參數(shù)pollfd,將文件描述符和事件都定義其中,任何事件都被統(tǒng)一處理,使得編程接口簡潔

select和poll每次調(diào)用都返回整個(gè)用戶注冊的事件集合(就緒的和未就緒的);索引就緒文件描述符的時(shí)間復(fù)雜度:O(n)

epoll:在內(nèi)核中維護(hù)一個(gè)事件表,通過epoll_ctl往其中添加、刪除、修改事件,epoll_wait都直接從內(nèi)核事件表中取得用戶注冊事件,而不用反復(fù)從用戶空間讀入事件,索引就緒文件描述符的時(shí)間復(fù)雜度:O(1)

最大支持文件數(shù):

select :1024

poll、epoll:系統(tǒng)打開最大文件描述符的數(shù)目;65535

工作模式:

select和poll只能工作在相對低效的LT模式,

epoll可以工作在ET高效模式,epoll還支持EPOLLONESHOT事件,該事件進(jìn)一步減少事件被觸發(fā)次數(shù);

具體實(shí)現(xiàn):

select和poll:采用輪詢方式,每次調(diào)用都要掃描整個(gè)注冊文件描述符

epoll_wait:無需輪詢整個(gè)文件描述符,根據(jù)下標(biāo)直接定位(events數(shù)組中即就緒文件),算法復(fù)雜度:O(1)

當(dāng)活動(dòng)連接比較多的時(shí)候,epoll_wait的效率未必比select和poll高,因?yàn)榇藭r(shí)回調(diào)函數(shù)被觸發(fā)的過于頻繁,epoll_wait適用于連接數(shù)量多,但活動(dòng)連接少的情況

3、select()和poll()模式主要有3個(gè)缺點(diǎn)


(1)、select()的fd有最大的限制,1024/2048,并發(fā)數(shù)被限制了,poll的并發(fā)數(shù)與epoll相同

(2)、內(nèi)存拷貝問題,每次都需要將fd集合從用戶態(tài)拷貝到內(nèi)核態(tài),開銷較大,內(nèi)存拷貝方法內(nèi)核把fd通知給用戶空間

(3)、select模式每次都會(huì)線性的掃描從內(nèi)核傳遞進(jìn)來的fd集合,效率比較低

引出了epoll模型,epoll模型是Linux獨(dú)有的I/O復(fù)用模型,做了很大的改進(jìn)

(1)、epoll模型沒有最大并發(fā)連接的限制,所可以并發(fā)的數(shù)目很系統(tǒng)內(nèi)存有很大的關(guān)系

(2)、epoll模型使用了"共享內(nèi)存",不存在內(nèi)存拷貝的問題了

(3)、epoll模型只管連接"就緒"的,而跟連接總數(shù)無關(guān),也就不存在遍歷了

4、epoll模型的高效關(guān)鍵在于數(shù)據(jù)結(jié)構(gòu)的設(shè)計(jì)


typedef?union?epoll_data?{
?void????????*ptr;
?int??????????fd;??//一般情況下,都用的是這個(gè)文件描述符
?uint32_t?????u32;
?uint64_t?????u64;
}?epoll_data_t;

struct?epoll_event?{
???uint32_t?????events;??????/*?Epoll?events?*/
???epoll_data_t?data;????????/*?User?data?variable?*/
};

epoll_data是一個(gè)union結(jié)構(gòu)體,保存了:fd,指針,利用其就可以直接定位目標(biāo)了

epoll_wait()

5、對epoll_wait()函數(shù)的核心理解


(1)、返回值:事件表中就緒客戶端的個(gè)數(shù);等待隊(duì)列

(2)、參數(shù)events:將事件表中的就緒客戶端的信息放到了events數(shù)組中。

epoll()的核心思想

就是創(chuàng)建一個(gè)內(nèi)核事件表,存放所監(jiān)聽客戶端的套接字和當(dāng)前的事件,在利用epoll_wait()函數(shù)查找就緒的套接字,最后經(jīng)過增加、刪除、修改利用epoll_ctl()函數(shù)進(jìn)行
#字節(jié)跳動(dòng)2021秋招開始了##字節(jié)跳動(dòng)##騰訊##筆試題目#
全部評論
日常工作較忙,很少上???。 1、對于找實(shí)習(xí)時(shí),被卡簡歷,需要參考我簡歷模板的。 2、對于大廠實(shí)習(xí)期間的疑惑,暑期實(shí)習(xí)打法相關(guān)、秋招面試相關(guān)、簡歷修改相關(guān),想了解更清楚的同學(xué)。 都可以加我微信聯(lián)系我(要簡歷或者咨詢實(shí)習(xí)):18519336960,備注:牛友
3 回復(fù) 分享
發(fā)布于 2020-07-03 21:16
支持。六大高并發(fā)模型分析得很到位,公眾號中都是精華的總結(jié),推薦~
1 回復(fù) 分享
發(fā)布于 2020-07-04 08:29
哈哈哈,來晚了,沒占到一樓,支持!
1 回復(fù) 分享
發(fā)布于 2020-07-04 02:11
前排支持?。。?!
1 回復(fù) 分享
發(fā)布于 2020-07-03 21:37
支持~
點(diǎn)贊 回復(fù) 分享
發(fā)布于 2020-07-03 22:43
支持!!!
點(diǎn)贊 回復(fù) 分享
發(fā)布于 2020-07-03 22:12

相關(guān)推薦

king122:實(shí)習(xí)經(jīng)歷可以重點(diǎn)寫這里這里寫的清晰一點(diǎn),分點(diǎn)寫。技能特長一般是放在上面的,而且你的實(shí)習(xí)經(jīng)歷不能只寫實(shí)現(xiàn)了一些簡單的接口,你要去寫一些難點(diǎn)和亮點(diǎn)。甚至可以寫一些數(shù)字指標(biāo)上去,只要你能配合業(yè)務(wù)講出來,根據(jù)我說的這些自己簡單包裝一下,面試應(yīng)該會(huì)更多,至于筆試和八股,那就只能純靠自己了,對項(xiàng)目包裝感興趣可以找我
點(diǎn)贊 評論 收藏
分享
浪漫主義的虹夏:都是校友,還是同屆,我就說直白點(diǎn),不委婉了,我相信你應(yīng)該也不是個(gè)玻璃心,首先你覺得一個(gè)雙非的績點(diǎn)寫簡歷上有用嗎?班長職務(wù)有用嗎?ccf有用嗎?企業(yè)會(huì)關(guān)心你高數(shù)滿分與否嗎?第二,第一個(gè)項(xiàng)目實(shí)在太爛,一眼就能看出是外賣,還是毫無包裝的外賣,使用JWT來鑒權(quán),把熱點(diǎn)數(shù)據(jù)放進(jìn)Redis這兩個(gè)點(diǎn)居然還能寫進(jìn)簡歷里,說難聽點(diǎn)這兩個(gè)東西都是學(xué)個(gè)幾十分鐘,調(diào)用個(gè)API就能完成的事情,在雙非一本的條件下,這種項(xiàng)目你覺得能拿出手嗎,第二個(gè)項(xiàng)目你寫的東西和你的求職方向有任何的匹配嗎?第三,計(jì)設(shè)那一塊毫無價(jià)值,如果想突出自己會(huì)前端,直接寫入專業(yè)技能不行嗎,最后,專業(yè)技能里像深入理解JVM底層原理這種你覺得這句話你自己真的能匹配嗎?都是校友加上同屆,我措辭直接,但希望能點(diǎn)出你的問題,想進(jìn)大廠還得繼續(xù)沉淀項(xiàng)目和學(xué)習(xí)
點(diǎn)贊 評論 收藏
分享
評論
16
120
分享

創(chuàng)作者周榜

更多
??途W(wǎng)
牛客企業(yè)服務(wù)