天天看點

(P48)muduo庫使用例子(七):高效率多線程異步日志

文章目錄

    • 1.多線程程式日志庫要求

1.多線程程式日志庫要求

  • 線程安全,即多個線程可以并發寫日志,兩個線程的日志消息不會出現交織。

    (1)用一個全局的mutex保護IO

    (2)每個線程單獨寫一個日志檔案

  • 前者造成全部線程搶占一個鎖,會造成寫日志變成了串行
  • 後者有可能讓業務線程阻塞在寫磁盤操作上,影響業務線程的并發能力
  • 解決辦法:用一個背景線程(日志線程,後端線程)負責收集日志消息,并寫入日志檔案,其他業務線程(前端線程)隻管往這個“日志線程”發送日志消息(不是實時的),這稱為“異步日志”,并不影響業務線程并發寫日志,前端的業務線程不會阻塞的,因為是寫到緩沖區中的。

    (1)生産者與消費者

    前端(業務線程)生産者,多個

    後端(日志線程)消費者,1個

    缺點:寫檔案操作比較頻繁,效率比較低

生産者
p(semfull)
	p(mutex)
	往隊列中添加一條日志消息
	v(mutex)
v(semempty)

消費者
p(semempty)
	p(mutex)
	從隊列中取出所有的日志消息,寫入到檔案中
	v(mutex)
v(semfull)
           
  • muduo采用多緩沖機制,multiple buffering

    前端(業務線程)生産者,多個

    後端(日志線程)消費者,1個

    優點:使得前端的業務線程與後端的日志線程能夠并發,且寫日志不太頻繁,提高了效率。

    (1)前端業務線程将日志寫到currentBuffer_,nextBuffer_是後備的一塊緩沖區,buffers_是要寫入到日志檔案的緩沖區清單;

    (2)currentBuffer_寫滿後,添加到buffers_,會通知後端的日志線程寫日志檔案,currentBuffer_不寫滿,後端線程是不會将資料寫入到日志檔案中的,但是此時其他業務線程往nextBuffer_又寫入一部分資料了,沒寫滿,此時currentBuffer_需要指向nextBuffer_所指向的緩沖區;

    (3)後端日志線程得到通知後,此時前端的currentBuffer_沒有滿,也會将其添加到buffers_中,前端從buffers_中取出資料;将buwBuffer1_緩沖區給currentBuffer_,将newBuffer2_緩沖區給nextBuffer_,保證前端的業務線程還能寫日志消息到緩沖區中。

    (4)當buffer_緩沖區的資料寫完之後,還需要預留2塊緩沖區給newBuffer1_和newBuffer2_

    (P48)muduo庫使用例子(七):高效率多線程異步日志
    (P48)muduo庫使用例子(七):高效率多線程異步日志
    (P48)muduo庫使用例子(七):高效率多線程異步日志
    (P48)muduo庫使用例子(七):高效率多線程異步日志
    (P48)muduo庫使用例子(七):高效率多線程異步日志
    (P48)muduo庫使用例子(七):高效率多線程異步日志
  • eg:48\jmuduo\muduo\base\AsyncLogging.h

    48\jmuduo\muduo\base\AsyncLogging.cc

  • eg測試:48\jmuduo\muduo\base\tests\AsyncLogging_test.cc

    29:34