muduo線程的啟動(dòng)

上篇說(shuō)了多線程處理的概述椿争,這篇說(shuō)說(shuō)具體實(shí)現(xiàn)典唇。

muduo的多線程是由線程池中啟動(dòng)的弥雹。線程池類EventLoopThreadPool在TcpServer類中創(chuàng)建一個(gè)心得實(shí)例猜极。發(fā)現(xiàn)在muduo中,各種類的關(guān)系基本上引用和包含即組合關(guān)系色查,很少有派生關(guān)系的,沒(méi)有繼承關(guān)系就沒(méi)有虛函數(shù)的應(yīng)用了撞芍。

可能陳碩覺(jué)得繼承關(guān)系比較復(fù)雜秧了,耦合度太高,破壞整體設(shè)計(jì)序无。但是我覺(jué)得muduo中那么多不同種類的智能指針验毡,還有基于boost或std的函數(shù)綁定衡创,本身就夠復(fù)雜的了。所以我打算有時(shí)間用c語(yǔ)言來(lái)改寫一下muduo晶通,把那些智能指針璃氢,函數(shù)綁定等弱化,只關(guān)注網(wǎng)絡(luò)框架本身狮辽。不過(guò)說(shuō)實(shí)話一也,muduo本身就是基于C++的,用智能指針和函數(shù)綁定很正常喉脖,而且人家還用得非常到位椰苟。所以要想往C++方面發(fā)展,還是得精通上面的知識(shí)树叽。我本身是搞C++舆蝴,而且搞了很久,而且決定一直搞下去题诵。不過(guò)在接觸c項(xiàng)目洁仗,腳本語(yǔ)言,還有現(xiàn)代網(wǎng)絡(luò)并發(fā)語(yǔ)言golang之后性锭,還是覺(jué)得用C++寫項(xiàng)目開(kāi)發(fā)效率太低了赠潦,而且很難駕馭,指針就是一個(gè)雷區(qū)篷店。精通C++的時(shí)間與其收獲性價(jià)比是很低的祭椰,所以我決定以后不再畫太多的時(shí)間在C++上,對(duì)于C++項(xiàng)目疲陕,我只是關(guān)注其框架本身方淤。

好了廢話少說(shuō)。EventLoopThreadPool的start在TcpServer的start中調(diào)用蹄殃,他會(huì)創(chuàng)建n個(gè)線程并啟動(dòng)携茂,n是EventLoopThreadPool的成員變量,可以配置诅岩,也可以是0個(gè)讳苦。每個(gè)線程是EventLoopThread的實(shí)例。而EventLoopThread有個(gè)組合對(duì)象Thread吩谦,他才是線程創(chuàng)建和啟動(dòng)真正的地方鸳谜。代碼如下:

void TcpServer::start()
{
  if (started_.getAndSet(1) == 0)
  {
    threadPool_->start(threadInitCallback_);

    assert(!acceptor_->listenning());
    loop_->runInLoop(
        std::bind(&Acceptor::listen, get_pointer(acceptor_)));
  }
}
void EventLoopThreadPool::start(const ThreadInitCallback& cb)
{
  assert(!started_);
  baseLoop_->assertInLoopThread();

  started_ = true;

  for (int i = 0; i < numThreads_; ++i)
  {
    char buf[name_.size() + 32];
    snprintf(buf, sizeof buf, "%s%d", name_.c_str(), i);
    EventLoopThread* t = new EventLoopThread(cb, buf);
    threads_.push_back(std::unique_ptr<EventLoopThread>(t));
    loops_.push_back(t->startLoop());
  }
  if (numThreads_ == 0 && cb)
  {
    cb(baseLoop_);
  }
}
void Thread::start()
{
  assert(!started_);
  started_ = true;
  // FIXME: move(func_)
  detail::ThreadData* data = new detail::ThreadData(func_, name_, &tid_, &latch_);
  if (pthread_create(&pthreadId_, NULL, &detail::startThread, data))
  {
    started_ = false;
    delete data; // or no delete?
    LOG_SYSFATAL << "Failed in pthread_create";
  }
  else
  {
    latch_.wait();
    assert(tid_ > 0);
  }
}

Thread的線程函數(shù)已經(jīng)綁定在了EventLoopThread::threadFunc里,這個(gè)是在EventLoopThread構(gòu)造函數(shù)是初始化的式廷。代碼如下:

void EventLoopThread::threadFunc()
{
  EventLoop loop;

  if (callback_)
  {
    callback_(&loop);
  }

  {
    MutexLockGuard lock(mutex_);
    loop_ = &loop;
    cond_.notify();
  }

  loop.loop();
  //assert(exiting_);
  loop_ = NULL;
}

這里有個(gè)問(wèn)題是咐扭,主線程會(huì)加入新線程的loop實(shí)例,而這個(gè)loop實(shí)例又是在線程的線程函數(shù)里創(chuàng)建的。所以很顯然主線程和新線程有個(gè)同步的過(guò)程蝗肪,并且多個(gè)新線程之間有臨界區(qū)的問(wèn)題袜爪。這些是用條件變量pthread_cond_t和互斥變量mutext來(lái)實(shí)現(xiàn)的。

新線程線程函數(shù)在棧上申明一個(gè)EventLoop對(duì)象之后薛闪,便通知主線程了辛馆。這使得主線程返回,而新線程函數(shù)中l(wèi)oop開(kāi)始運(yùn)作循環(huán)了豁延。那么主線程又是如何跨線程調(diào)用新線程的函數(shù)的呢昙篙?這個(gè)下篇再說(shuō)。

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末术浪,一起剝皮案震驚了整個(gè)濱河市瓢对,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌胰苏,老刑警劉巖硕蛹,帶你破解...
    沈念sama閱讀 206,482評(píng)論 6 481
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場(chǎng)離奇詭異硕并,居然都是意外死亡法焰,警方通過(guò)查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 88,377評(píng)論 2 382
  • 文/潘曉璐 我一進(jìn)店門倔毙,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái)埃仪,“玉大人,你說(shuō)我怎么就攤上這事陕赃÷羊龋” “怎么了?”我有些...
    開(kāi)封第一講書人閱讀 152,762評(píng)論 0 342
  • 文/不壞的土叔 我叫張陵么库,是天一觀的道長(zhǎng)傻丝。 經(jīng)常有香客問(wèn)我,道長(zhǎng)诉儒,這世上最難降的妖魔是什么葡缰? 我笑而不...
    開(kāi)封第一講書人閱讀 55,273評(píng)論 1 279
  • 正文 為了忘掉前任,我火速辦了婚禮忱反,結(jié)果婚禮上泛释,老公的妹妹穿的比我還像新娘。我一直安慰自己温算,他們只是感情好怜校,可當(dāng)我...
    茶點(diǎn)故事閱讀 64,289評(píng)論 5 373
  • 文/花漫 我一把揭開(kāi)白布。 她就那樣靜靜地躺著注竿,像睡著了一般韭畸。 火紅的嫁衣襯著肌膚如雪宇智。 梳的紋絲不亂的頭發(fā)上蔓搞,一...
    開(kāi)封第一講書人閱讀 49,046評(píng)論 1 285
  • 那天胰丁,我揣著相機(jī)與錄音,去河邊找鬼喂分。 笑死锦庸,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的蒲祈。 我是一名探鬼主播甘萧,決...
    沈念sama閱讀 38,351評(píng)論 3 400
  • 文/蒼蘭香墨 我猛地睜開(kāi)眼,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼梆掸!你這毒婦竟也來(lái)了扬卷?” 一聲冷哼從身側(cè)響起,我...
    開(kāi)封第一講書人閱讀 36,988評(píng)論 0 259
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤酸钦,失蹤者是張志新(化名)和其女友劉穎怪得,沒(méi)想到半個(gè)月后,有當(dāng)?shù)厝嗽跇?shù)林里發(fā)現(xiàn)了一具尸體卑硫,經(jīng)...
    沈念sama閱讀 43,476評(píng)論 1 300
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡徒恋,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 35,948評(píng)論 2 324
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了欢伏。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片入挣。...
    茶點(diǎn)故事閱讀 38,064評(píng)論 1 333
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖硝拧,靈堂內(nèi)的尸體忽然破棺而出径筏,到底是詐尸還是另有隱情,我是刑警寧澤障陶,帶...
    沈念sama閱讀 33,712評(píng)論 4 323
  • 正文 年R本政府宣布滋恬,位于F島的核電站,受9級(jí)特大地震影響咸这,放射性物質(zhì)發(fā)生泄漏夷恍。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 39,261評(píng)論 3 307
  • 文/蒙蒙 一媳维、第九天 我趴在偏房一處隱蔽的房頂上張望酿雪。 院中可真熱鬧,春花似錦侄刽、人聲如沸指黎。這莊子的主人今日做“春日...
    開(kāi)封第一講書人閱讀 30,264評(píng)論 0 19
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)醋安。三九已至杂彭,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間吓揪,已是汗流浹背亲怠。 一陣腳步聲響...
    開(kāi)封第一講書人閱讀 31,486評(píng)論 1 262
  • 我被黑心中介騙來(lái)泰國(guó)打工, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留柠辞,地道東北人团秽。 一個(gè)月前我還...
    沈念sama閱讀 45,511評(píng)論 2 354
  • 正文 我出身青樓,卻偏偏與公主長(zhǎng)得像叭首,于是被迫代替她去往敵國(guó)和親习勤。 傳聞我的和親對(duì)象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 42,802評(píng)論 2 345

推薦閱讀更多精彩內(nèi)容