0
  • 聊天消息
  • 系統(tǒng)消息
  • 評論與回復(fù)
登錄后你可以
  • 下載海量資料
  • 學(xué)習(xí)在線課程
  • 觀看技術(shù)視頻
  • 寫文章/發(fā)帖/加入社區(qū)
會員中心
創(chuàng)作中心

完善資料讓更多小伙伴認(rèn)識你,還能領(lǐng)取20積分哦,立即完善>

3天內(nèi)不再提示

詳解Linux Epoll多線程擴(kuò)展性問題

xCb1_yikoulinux ? 來源:小梁編程匯 ? 作者:小梁編程匯 ? 2022-07-06 12:05 ? 次閱讀

內(nèi)容目錄

1. 引言2. 脈絡(luò)3 epoll 多線程擴(kuò)展性3.1特定TCP listen fd的accept(2) 的問題3.1.1 水平觸發(fā)的問題:不必要的喚醒3.1.2 邊緣觸發(fā)的問題:不必要的喚醒以及饑餓3.1.3 怎樣才是正確的做法?3.1.4 其他方案3.2 大量TCP連接的read(2)的問題3.2.1 水平觸發(fā)的問題:數(shù)據(jù)亂序3.2.2 邊緣觸發(fā)的問題:數(shù)據(jù)亂序3.2.3 怎樣才是正確的做法?3.3 epoll load balance 總結(jié)4. epoll之file descriptor與file description4.1 總結(jié)5 引用

1引言

本文來自 Marek’s 博客中 I/O multiplexing part 系列之三和四,原文一共有四篇,主要講 Linux 上 IO 多路復(fù)用的一些問題,本文加入了我的一些個(gè)人理解,如有不對之處敬請指出。原文鏈接如下:

ThehistoryoftheSelect(2)syscall[1] Select(2)isfundamentallybroken[2] Epollisfundamentallybroken1/2[3] Epollisfundamentallybroken2/2[4]

2脈絡(luò)

系列三和系列四分別講 epoll(2) 存在的兩個(gè)不同的問題:

  1. 系列三主要講 epoll 的多線程擴(kuò)展性的問題

  2. 系列四主要講 epoll 所注冊的 fd (file descriptor) 和實(shí)際內(nèi)核中控制的結(jié)構(gòu) file description 擁有不同的生命周期

我們在此也按照該順序進(jìn)行闡述。

3 epoll 多線程擴(kuò)展性

epoll 的多線程擴(kuò)展性的問題主要體現(xiàn)在做多核之間負(fù)載均衡上,有兩個(gè)典型的場景:

  1. 一個(gè) TCP 服務(wù)器,對同一個(gè) listen fd 在多個(gè) CPU 上調(diào)用 accept(2) 系統(tǒng)調(diào)用

  2. 大量 TCP 連接調(diào)用 read(2) 系統(tǒng)調(diào)用上

3.1 特定 TCP listen fd 的 accept(2) 的問題

一個(gè)典型的場景是一個(gè)需要處理大量短連接的 HTTP 1.0 服務(wù)器,由于需要 accept() 大量的 TCP 建連請求,所以希望把這些 accept() 分發(fā)到不同的 CPU 上來處理,以充分利用多 CPU 的能力。

這在實(shí)際生產(chǎn)環(huán)境是存在的, Tom Herbert 報(bào)告有應(yīng)用需要處理每秒 4 萬個(gè)建連請求;當(dāng)有這么多請求的時(shí)候,很顯然,將其分散到不同的 CPU 上是合理的。

然后實(shí)際上,事情并沒有這么簡單,直到 Linux 4.5 內(nèi)核,都無法通過 epoll(2) 把這些請求水平擴(kuò)展到其他 CPU 上。下面我們來看看 epoll 的兩種模式 LT(level trigger, 水平觸發(fā)) 和 ET(edge trigger, 邊緣觸發(fā)) 在處理這種情況下的問題。

3.1.1 水平觸發(fā)的問題:不必要的喚醒

一個(gè)愚蠢的做法是是將同一個(gè) epoll fd 放到不同的線程上來 epoll_wait(),這樣做顯然行不通,同樣,將同一個(gè)用于 accept 的 fd 加到不同的線程中的 epoll fd 中也行不通。

這是因?yàn)?epoll 的水平觸發(fā)模式和 select(2) 一樣存在 “驚群效應(yīng)”,在不加特殊標(biāo)志的水平觸發(fā)模式下,當(dāng)一個(gè)新建連接請求過來時(shí),所有的 worker 線程都都會被喚醒,下面是一個(gè)這種 case 的例子:

11. 內(nèi)核:收到一個(gè)新建連接的請求
22. 內(nèi)核:由于"驚群效應(yīng)",喚醒兩個(gè)正在 epoll_wait()的線程 A 和線程 B
33. 線程A:epoll_wait()返回
44. 線程B:epoll_wait()返回
55. 線程A:執(zhí)行 accept()并且成功
66. 線程B:執(zhí)行 accept()失敗,accept()返回 EAGAIN

其中,線程 B 的喚醒完全沒有必要,僅僅只是浪費(fèi)寶貴的 CPU 資源而已,水平觸發(fā)模式的 epoll 的擴(kuò)展性很差。

3.1.2 邊緣觸發(fā)的問題:不必要的喚醒以及饑餓

既然水平觸發(fā)模式不行,那是不是邊緣觸發(fā)模式會更好呢?實(shí)際上并沒有。我們來看看下面這個(gè)例子:

11. 內(nèi)核:收到第一個(gè)連接請求。線程 A 和線程 B 兩個(gè)線程都在 epoll_wait()上等待。由于采用邊緣觸發(fā)模式,所以只有一個(gè)線程會收到通知。這里假定線程 A 收到通知
22. 線程A:epoll_wait()返回
33. 線程A:調(diào)用 accpet()并且成功
44. 內(nèi)核:此時(shí) accept queue 為空,所以將邊緣觸發(fā)的 socket 的狀態(tài)從可讀置成不可讀
55. 內(nèi)核:收到第二個(gè)建連請求
66. 內(nèi)核:此時(shí),由于線程 A 還在執(zhí)行 accept()處理,只剩下線程 B 在等待 epoll_wait(),于是喚醒線程 B
77. 線程A:繼續(xù)執(zhí)行 accept()直到返回 EAGAIN
88. 線程B:執(zhí)行 accept(),并返回 EAGAIN,此時(shí)線程 B 可能有點(diǎn)困惑("明明通知我有事件,結(jié)果卻返回 EAGAIN")
99. 線程A:再次執(zhí)行 accept(),這次終于返回 EAGAIN

可以看到在上面的例子中,線程 B 的喚醒是完全沒有必要的。另外,事實(shí)上邊緣觸發(fā)模式還存在饑餓的問題,我們來看下面這個(gè)例子:

11. 內(nèi)核:接收到兩個(gè)建連請求。線程 A 和線程 B 兩個(gè)線程都在等在 epoll_wait()。由于采用邊緣觸發(fā)模式,只有一個(gè)線程會被喚醒,我們這里假定線程 A 先被喚醒
22. 線程A:epoll_wait()返回
33. 線程A:調(diào)用 accpet()并且成功
44. 內(nèi)核:收到第三個(gè)建連請求。由于線程 A 還沒有處理完(沒有返回 EAGAIN),當(dāng)前 socket 還處于可讀的狀態(tài),由于是邊緣觸發(fā)模式,所有不會產(chǎn)生新的事件
55. 線程A:繼續(xù)執(zhí)行 accept()希望返回 EAGAIN 再進(jìn)入 epoll_wait()等待,然而它又 accept()成功并處理了一個(gè)新連接
66. 內(nèi)核:又收到了第四個(gè)建連請求
77. 線程A:又繼續(xù)執(zhí)行 accept(),結(jié)果又返回成功

在這個(gè)例子中個(gè),這個(gè) socket 只有一次從不可讀狀態(tài)變成可讀狀態(tài),由于 socket 處于邊緣觸發(fā)模式,內(nèi)核只會喚醒 epoll_wait() 一次。在這個(gè)例子中個(gè),所有的建連請求全都會給線程 A,導(dǎo)致這個(gè)負(fù)載均衡根本沒有生效,線程 A 很忙而線程 B 沒有活干。

3.1.3 怎樣才是正確的做法?

既然水平觸發(fā)和邊緣觸發(fā)都不行,那怎樣才是正確的做法呢?有兩種 workaround 的方式:

  1. 最好的也是唯一支持可擴(kuò)展的方式是使用從 Linux 4.5+ 開始出現(xiàn)的水平觸發(fā)模式新增的 EPOLLEXCLUSIVE 標(biāo)志,這個(gè)標(biāo)志會保證一個(gè)事件只有一個(gè) epoll_wait() 會被喚醒,避免了 “驚群效應(yīng)”,并且可以在多個(gè) CPU 之間很好的水平擴(kuò)展。

  2. 當(dāng)內(nèi)核不支持EPOLLEXCLUSIVE 時(shí),可以通過 ET 模式下的 EPOLLONESHOT模擬 LT + EPOLLEXCLUSIVE 的效果,當(dāng)然這樣是有代價(jià)的,需要在每個(gè)事件處理完之后額外多調(diào)用一次 epoll_ctl(EPOLL_CTL_MOD) 重置這個(gè) fd。這樣做可以將負(fù)載均分到不同的 CPU 上,但是同一時(shí)刻,只能有一個(gè) worker 調(diào)用 accept(2)。顯然,這樣又限制了處理 accept(2) 的吞吐。下面是這樣做的例子:

  3. 內(nèi)核:接收到兩個(gè)建連請求。線程 A 和 線程 B 兩個(gè)線程都在等在 epoll_wait()。由于采用邊緣觸發(fā)模式,只有一個(gè)線程會被喚醒,我們這里假定線程 A 先被喚醒

  4. 線程A:epoll_wait() 返回

  5. 線程A:調(diào)用 accpet() 并且成功

  6. 線程A:調(diào)用 epoll_ctl(EPOLL_CTL_MOD),這樣會重置 EPOLLONESHOT 狀態(tài)并將這個(gè) socket fd 重新準(zhǔn)備好 “

3.1.4 其他方案

當(dāng)然,如果不依賴于 epoll() 的話,也還有其他方案。一種方案是使用 SO_REUSEPORT 這個(gè) socket option,創(chuàng)建多個(gè) listen socket 共用一個(gè)端口號,不過這種方案其實(shí)也存在問題: 當(dāng)一個(gè) listen socket fd 被關(guān)了,已經(jīng)被分到這個(gè) listen socket fd 的 accept 隊(duì)列上的請求會被丟掉,具體可以參考 https://engineeringblog.yelp.com/2015/04/true-zero-downtime-haproxy-reloads.html 和 LWN 上的 comment[5]

從 Linux 4.5 開始引入了 SO_ATTACH_REUSEPORT_CBPFSO_ATTACH_REUSEPORT_EBPF 這兩個(gè) BPF 相關(guān)的 socket option。通過巧妙的設(shè)計(jì),應(yīng)該可以避免掉建連請求被丟掉的情況。

3.2 大量 TCP 連接的 read(2) 的問題

除了 3.1 中說的 accept(2) 的問題之外, 普通的 read(2) 在多核系統(tǒng)上也會有擴(kuò)展性的問題。設(shè)想以下場景:一個(gè) HTTP 服務(wù)器,需要跟大量的 HTTP client 通信,你希望盡快的處理每個(gè)客戶端的請求。而每個(gè)客戶端連接的請求的處理時(shí)間可能并不一樣,有些快有些慢,并且不可預(yù)測,因此簡單的將這些連接切分到不同的 CPU 上,可能導(dǎo)致平均響應(yīng)時(shí)間變長。一種更好的排隊(duì)策略可能是:用一個(gè) epoll fd 來管理這些連接并設(shè)置 EPOLLEXCLUSIVE,然后多個(gè) worker 線程來 epoll_wait(),取出就緒的連接并處理[注1]。油管上有個(gè)視頻介紹這種稱之為 “combined queue” 的模型。

下面我們來看看 epoll 處理這種模型下的問題:

3.2.1 水平觸發(fā)的問題:數(shù)據(jù)亂序

實(shí)際上,由于水平觸發(fā)存在的 “驚群效應(yīng)”,我們并不想用該模型。另外,即使加上 EPOLLEXCLUSIVE 標(biāo)志,仍然存在數(shù)據(jù)競爭的情況,我們來看看下面這個(gè)例子:

11. 內(nèi)核:收到 2047 字節(jié)的數(shù)據(jù)
22. 內(nèi)核:線程 A 和線程 B 兩個(gè)線程都在 epoll_wait(),由于設(shè)置了 EPOLLEXCLUSIVE,內(nèi)核只會喚醒一個(gè)線程,假設(shè)這里先喚醒線程 A
33. 線程A:epoll_wait()返回
44. 內(nèi)核:內(nèi)核又收到 2 個(gè)字節(jié)的數(shù)據(jù)
55. 內(nèi)核:線程 A 還在干活,當(dāng)前只有線程 B 在 epoll_wait(),內(nèi)核喚醒線程 B
66. 線程A:調(diào)用 read(2048)并讀走 2048 字節(jié)數(shù)據(jù)
77. 線程B:調(diào)用 read(2048)并讀走剩下的 1 字節(jié)數(shù)據(jù)

這上述場景中,數(shù)據(jù)會被分片到兩個(gè)不同的線程,如果沒有鎖保護(hù)的話,數(shù)據(jù)可能會存在亂序。

3.2.2 邊緣觸發(fā)的問題:數(shù)據(jù)亂序

既然水平觸發(fā)模型不行,那么邊緣觸發(fā)呢?實(shí)際上也存在相同的競爭,我們看看下面這個(gè)例子:

 11. 內(nèi)核:收到 2048 字節(jié)的數(shù)據(jù)
 22. 內(nèi)核:線程 A 和線程 B 兩個(gè)線程都在 epoll_wait(),由于設(shè)置了 EPOLLEXCLUSIVE,內(nèi)核只會喚醒一個(gè)線程,假設(shè)這里先喚醒線程 A
 33. 線程A:epoll_wait()返回
 44. 線程A:調(diào)用 read(2048)并返回 2048 字節(jié)數(shù)據(jù)
 55. 內(nèi)核:緩沖區(qū)數(shù)據(jù)全部已經(jīng)讀完,又重新將該 fd 掛到 epoll 隊(duì)列上
 66. 內(nèi)核:收到 1 字節(jié)的數(shù)據(jù)
 77. 內(nèi)核:線程 A 還在干活,當(dāng)前只有線程 B 在 epoll_wait(),內(nèi)核喚醒線程 B
 88. 線程B:epoll_wait()返回
 99. 線程B:調(diào)用 read(2048)并且只讀到了 1 字節(jié)數(shù)據(jù)
1010. 線程A:再次調(diào)用 read(2048),此時(shí)由于內(nèi)核緩沖區(qū)已經(jīng)沒有數(shù)據(jù),返回 EAGAIN

3.2.3 怎樣才是正確的做法?

實(shí)際上,要保證同一個(gè)連接的數(shù)據(jù)始終落到同一個(gè)線程上,在上述 epoll 模型下,唯一的方法就是 epoll_ctl 的時(shí)候加上 EPOLLONESHOT 標(biāo)志,然后在每次處理完重新把這個(gè) socket fd 加到 epoll 里面去。

3.3 epoll load balance 總結(jié)

要正確的用好 epoll(2) 并不容易,要用 epoll 實(shí)現(xiàn)負(fù)載均衡并且避免數(shù)據(jù)競爭,必須掌握好 EPOLLONESHOTEPOLLEXCLUSIVE 這兩個(gè)標(biāo)志。而 EPOLLEXCLUSIVE 又是個(gè) epoll 后來新加的標(biāo)志,所以我們可以說 epoll 最初設(shè)計(jì)時(shí),并沒有想著支持這種多線程負(fù)載均衡的場景。

4. epoll 之 file descriptor 與 file description

這一章我們主要討論 epoll 的另一個(gè)大問題:file descriptor 與 file description 生命周期不一致的問題。

Foom 在 LWN[6] 上說道:

1顯然 epoll 存在巨大的設(shè)計(jì)缺陷,任何懂得 file descriptor 的人應(yīng)該都能看得出來。事實(shí)上當(dāng)你回望 epoll 的歷史,你會發(fā)現(xiàn)當(dāng)時(shí)實(shí)現(xiàn) epoll 的人們顯然并不怎么了解 file descriptor 和 file description 的區(qū)別。:(

實(shí)際上,epoll() 的這個(gè)問題主要在于它混淆了用戶態(tài)的 file descriptor (我們平常說的數(shù)字 fd) 和內(nèi)核態(tài)中真正用于實(shí)現(xiàn)的 file description。當(dāng)進(jìn)程調(diào)用 close(2) 關(guān)閉一個(gè) fd 時(shí),這個(gè)問題就會體現(xiàn)出來。

epoll_ctl(EPOLL_CTL_ADD) 實(shí)際上并不是注冊一個(gè) file descriptor (fd),而是將 fd 和 一個(gè)指向內(nèi)核 file description 的指針的對 (tuple) 一塊注冊給了 epoll,導(dǎo)致問題的根源在于,epoll 里管理的 fd 的生命周期,并不是 fd 本身的,而是內(nèi)核中相應(yīng)的 file description 的。

當(dāng)使用 close(2) 這個(gè)系統(tǒng)調(diào)用關(guān)掉一個(gè) fd 時(shí),如果這個(gè) fd 是內(nèi)核中 file description 的唯一引用時(shí),內(nèi)核中的 file description 也會跟著一并被刪除,這樣是 OK 的;但是當(dāng)內(nèi)核中的 file description 還有其他引用時(shí),close 并不會刪除這個(gè) file descrption。這樣會導(dǎo)致當(dāng)這個(gè) fd 還沒有從 epoll 中挪出就被直接 close 時(shí),epoll() 還會在這個(gè)已經(jīng) close() 掉了的 fd 上上報(bào)事件。

這里以 dup(2) 系統(tǒng)調(diào)用為例來展示這個(gè)問題:

 1rfd,wfd=pipe()
 2write(wfd,"a")#Makethe"rfd"readable
 3
 4epfd=epoll_create()
 5epoll_ctl(efpd,EPOLL_CTL_ADD,rfd,(EPOLLIN,rfd))
 6
 7rfd2=dup(rfd)
 8close(rfd)
 9
10r=epoll_wait(epfd,-1ms)#Whatwillhappen?

由于 close(rfd) 關(guān)掉了這個(gè) rfd,你可能會認(rèn)為這個(gè) epoll_wait() 會一直阻塞不返回,而實(shí)際上并不是這樣。由于調(diào)用了 dup(),內(nèi)核中相應(yīng)的 file description 仍然還有一個(gè)引用計(jì)數(shù)而沒有被刪除,所以這個(gè) file descption 的事件仍然會上報(bào)給 epoll。因此 epoll_wait() 會給一個(gè)已經(jīng)不存在的 fd 上報(bào)事件。更糟糕的是,一旦你 close() 了這個(gè) fd,再也沒有機(jī)會把這個(gè)死掉的 fd 從 epoll 上摘除了,下面的做法都不行:

1epoll_ctl(efpd,EPOLL_CTL_DEL,rfd)
2epoll_ctl(efpd,EPOLL_CTL_DEL,rfd2)

Marc Lehmann 也提到這個(gè)問題:

1因此,存在 close 掉了一個(gè) fd,卻還一直從這個(gè) fd 上收到 epoll 事件的可能性。并且這種情況一旦發(fā)生,不管你做什么都無法恢復(fù)了。

因此,并不能依賴于 close() 來做清理工作,一旦調(diào)用了 close(),而正好內(nèi)核里面的 file description 還有引用,這個(gè) epoll fd 就再也修不好了,唯一的做法是把的 epoll fd 給干掉,然后創(chuàng)建一個(gè)新的并將之前那些 fd 全部再加到這個(gè)新的 epoll fd 上。所以記住這條忠告:

1永遠(yuǎn)記著先在調(diào)用close()之前,顯示的調(diào)用epoll_ctl(EPOLL_CTL_DEL)

4.1 總結(jié)

顯式的將 fd 從 epoll 上面刪掉在調(diào)用 close() 的話可以工作的很好,前提是你對所有的代碼都有掌控力。然后在一些場景里并不一直是這樣,譬如當(dāng)寫一個(gè)封裝 epoll 的庫,有時(shí)你并不能禁止用戶調(diào)用 close(2) 系統(tǒng)調(diào)用。因此,要寫一個(gè)基于 epoll 的輕量級的抽象層并不是一個(gè)輕松的事情。

另外,Illumos 也實(shí)現(xiàn)了一套 epoll() 機(jī)制,在他們的手冊上,明確提到 Linux 上這個(gè) epoll()/close() 的奇怪語義,并且拒絕支持。

希望本所提到的問題對于使用 Linux 上這個(gè)糟糕的 epoll() 設(shè)計(jì)的人有所幫助。


注1:筆者認(rèn)為該場景下或許直接用一個(gè) master 線程來做分發(fā),多個(gè) worker 線程做處理 或者采用每個(gè) worker 線程一個(gè)自己獨(dú)立的 epoll fd 可能是更好的方案。

審核編輯:湯梓紅
聲明:本文內(nèi)容及配圖由入駐作者撰寫或者入駐合作網(wǎng)站授權(quán)轉(zhuǎn)載。文章觀點(diǎn)僅代表作者本人,不代表電子發(fā)燒友網(wǎng)立場。文章及其配圖僅供工程師學(xué)習(xí)之用,如有內(nèi)容侵權(quán)或者其他違規(guī)問題,請聯(lián)系本站處理。 舉報(bào)投訴
  • Linux
    +關(guān)注

    關(guān)注

    87

    文章

    11182

    瀏覽量

    208549
  • 多線程
    +關(guān)注

    關(guān)注

    0

    文章

    277

    瀏覽量

    19882
  • epoll
    +關(guān)注

    關(guān)注

    0

    文章

    28

    瀏覽量

    2941

原文標(biāo)題:盤點(diǎn)Linux Epoll那些致命弱點(diǎn)

文章出處:【微信號:yikoulinux,微信公眾號:一口Linux】歡迎添加關(guān)注!文章轉(zhuǎn)載請注明出處。

收藏 人收藏

    評論

    相關(guān)推薦

    Linux多線程編程手冊

    Linux多線程編程手冊
    發(fā)表于 11-07 10:17

    提高Linux 內(nèi)核的穩(wěn)定性、可擴(kuò)展性核心點(diǎn)有哪些?

    /應(yīng)用程序服務(wù)器的企業(yè)用戶環(huán)境相關(guān)的工作負(fù)荷,也著重于提高 Linux 內(nèi)核的穩(wěn)定性、可擴(kuò)展性以及 (內(nèi)核) 與 Web 服務(wù)器/實(shí)用程序服務(wù)器的兼容性。最重要的并不是識別 Web 服務(wù)器和應(yīng)用程序服務(wù)器的缺陷。
    發(fā)表于 07-08 06:19

    Facebook的擴(kuò)展性挑戰(zhàn)討論

    今天我們一起來了解Facebook背后的軟件,看看作為當(dāng)今世界上訪問量最大的網(wǎng)站之一,F(xiàn)acebook是如何保證5億用戶的系統(tǒng)一直穩(wěn)定可靠的運(yùn)行。 Facebook的擴(kuò)展性挑戰(zhàn)
    發(fā)表于 07-17 07:22

    請問處理器擴(kuò)展性有什么重要之處?

    處理器擴(kuò)展性有什么重要之處?
    發(fā)表于 06-17 09:51

    linux多線程編程課件

    電子發(fā)燒友為您提供了linux多線程編程課件,希望對您學(xué)習(xí) linux 有所幫助。部分內(nèi)容如下: *1、多線程模型在單處理器模型和多處理器系統(tǒng)上,都能改善響應(yīng)時(shí)間和吞吐量。 *2、
    發(fā)表于 07-10 11:58 ?0次下載

    linux多線程編程開發(fā)

    本文中我們針對 Linux多線程編程的主要特性總結(jié)出 5 條經(jīng)驗(yàn),用以改善 Linux 多線程編程的習(xí)慣和避免其中的開發(fā)陷阱。在本文中,我們穿插一些 Windows 的編程用例用以
    發(fā)表于 12-26 14:24 ?55次下載
    <b class='flag-5'>linux</b><b class='flag-5'>多線程</b>編程開發(fā)

    VC-MFC多線程編程詳解

    VC編程中關(guān)于 MFC多線程編程的詳解文檔
    發(fā)表于 09-01 15:01 ?0次下載

    linux多線程編程技術(shù)

    (process)中只允許有一個(gè)線程,這樣多線程就意味著多進(jìn)程?,F(xiàn)在,多線程技術(shù)已經(jīng)被許多操作系統(tǒng)所支持,包括Windows/NT,當(dāng)然,也包括Linux。 為什么有了進(jìn)程的概念后,還
    發(fā)表于 10-24 16:01 ?5次下載

    基于軟件定義網(wǎng)絡(luò)控制可擴(kuò)展性研究

    軟件定義網(wǎng)絡(luò)(software-defined networking,簡稱SDN)遵循控制轉(zhuǎn)發(fā)分離的設(shè)計(jì)原則,其控制平面采用集中的控制邏輯,在提供靈活高效的網(wǎng)絡(luò)控制的同時(shí),也面臨著嚴(yán)重的可擴(kuò)展性問題
    發(fā)表于 12-19 18:07 ?0次下載
    基于軟件定義網(wǎng)絡(luò)控制可<b class='flag-5'>擴(kuò)展性</b>研究

    如何解決區(qū)塊鏈的可擴(kuò)展性問題

    “可擴(kuò)展性三難困境”是由以太坊聯(lián)合創(chuàng)始人維塔利克·布特林創(chuàng)造的一個(gè)術(shù)語。假設(shè)區(qū)塊鏈系統(tǒng)只能具有以下三種屬性中的兩種: · 去中心化——系統(tǒng)中的每個(gè)參與者只能訪問O(c)資源 · 可擴(kuò)展性
    發(fā)表于 03-20 10:30 ?2145次閱讀

    Linux下的多線程編程

    進(jìn)程(process)中只允許有一個(gè)線程,這樣多線程就意味著多進(jìn)程?,F(xiàn)在,多線程技術(shù)已經(jīng)被許多操作系統(tǒng)所支持,包括Windows/NT,當(dāng)然,也包括Linux?! 槭裁从辛诉M(jìn)程的概念
    發(fā)表于 04-02 14:43 ?586次閱讀

    信標(biāo)鏈將如何解決以太坊的擴(kuò)展性問題

    信標(biāo)鏈,英文名叫 Beacon Chain,Beacon ,意思就是燈塔,信號浮標(biāo)。它其實(shí)是以太坊 2.0 系統(tǒng)的核心。 信標(biāo)鏈?zhǔn)且环N全新的權(quán)益證明( PoS )區(qū)塊鏈,它是為了解決共識問題,而分片鏈( Shard Chains )的目的是解決以太坊的擴(kuò)展性問題。
    發(fā)表于 08-04 10:58 ?711次閱讀

    影響軟件高可擴(kuò)展性的六大因素

    軟件可擴(kuò)展性是一個(gè)有趣的話題。實(shí)現(xiàn)軟件可擴(kuò)展性涉及很多因素,我們在本文將討論一些與開發(fā)和運(yùn)維方面相關(guān)的因素。
    的頭像 發(fā)表于 02-17 16:13 ?8659次閱讀
    影響軟件高可<b class='flag-5'>擴(kuò)展性</b>的六大因素

    Linux多線程編程的知識點(diǎn)

    Hello、Hello大家好,我是木榮,今天我們繼續(xù)來聊一聊Linux多線程編程中的重要知識點(diǎn),詳細(xì)談?wù)?b class='flag-5'>多線程中同步和互斥機(jī)制。
    發(fā)表于 04-26 17:27 ?578次閱讀
    <b class='flag-5'>Linux</b>中<b class='flag-5'>多線程</b>編程的知識點(diǎn)

    擴(kuò)展性對物聯(lián)網(wǎng)管理系統(tǒng)有哪些影響?

    擴(kuò)展性對于物聯(lián)網(wǎng)管理系統(tǒng)的設(shè)計(jì)和開發(fā)非常重要,它直接影響著系統(tǒng)的性能、可靠性和能耗等方面,是評估一個(gè)系統(tǒng)優(yōu)劣的重要因素之一???b class='flag-5'>擴(kuò)展性對物聯(lián)網(wǎng)管理系統(tǒng)的影響主要體現(xiàn)在以下幾個(gè)方面:
    的頭像 發(fā)表于 10-11 15:15 ?445次閱讀