亚洲免费在线-亚洲免费在线播放-亚洲免费在线观看-亚洲免费在线观看视频-亚洲免费在线看-亚洲免费在线视频

第二人生的源碼分析(四十二)實現消息處理的線程

系統 1956 0
第二人生里使用線程循環來處理消息,這樣的結構就比較清晰。比如有一個寫文件的請求,就可以把這個請求放到線程隊列里,然后喚醒線程,讓線程處理這個請求。那么在第二人生里是怎么樣構造消息循環呢?又是怎么樣執行其它線程發過來的請求呢?帶著這兩個問題來分析下面這幾段代碼。
#001?void LLQueuedThread::run()
#002?{
?
下面實現消息循環。
#003? ???? while (1)
#004? ???? {
#005? ??????????? // this will block on the condition until runCondition() returns true, the thread is unpaused, or the thread leaves the RUNNING state.
?
下面檢查是否暫停線程執行。
#006? ??????????? checkPause();
#007? ???????????
?
檢查線程是否要結束循環。
#008? ??????????? if(isQuitting())
#009? ?????????????????? break;
#010?
#011? ??????????? //llinfos << "QUEUED THREAD RUNNING, queue size = " << mRequestQueue.size() << llendl;
#012?
?
標志線程已經非空閑狀態。
#013? ??????????? mIdleThread = FALSE;
#014? ???????????
?
調用processNextRequest函數來處理本線程消息隊列里的消息。
#015? ??????????? int res = processNextRequest();
#016? ??????????? if (res == 0)
#017? ??????????? {
#018? ?????????????????? mIdleThread = TRUE;
#019? ??????????? }
#020? ???????????
?
處理線程消息出錯,退出線程循環。
#021? ??????????? if (res < 0) // finished working and want to exit
#022? ??????????? {
#023? ?????????????????? break;
#024? ??????????? }
#025?
#026? ??????????? //LLThread::yield(); // thread should yield after each request??????????
#027? ???? }
#028?
#029? ???? llinfos << "QUEUED THREAD " << mName << " EXITING." << llendl;
#030?}
?
由線程接口類LLThread就知道,線程里主要處理函數是run(),而在LLThread繼承類LLQueuedThread里也就是實現了這個函數的功能,主要就是調用函數processNextRequest來處理消息隊列里的消息。下面就來分析函數processNextRequest的代碼,如下:
?
#001?
#002?S32 LLQueuedThread::processNextRequest()
#003?{
#004? ???? QueuedRequest *req;
#005? ???? // Get next request from pool
?
鎖住線程消息隊列。
#006? ???? lockData();
?
循環地找到可用的消息。
#007? ???? while(1)
#008? ???? {
#009? ??????????? req = NULL;
?
線程消息隊列為空,退出處理消息。
#010? ??????????? if (mRequestQueue.empty())
#011? ??????????? {
#012? ?????????????????? break;
#013? ??????????? }
?
獲取第一個消息請求。
#014? ??????????? req = *mRequestQueue.begin();
?
刪除第一個消息請求。
#015? ??????????? mRequestQueue.erase(mRequestQueue.begin());
?
判斷是否丟掉這個消息請求。
#016? ??????????? if ((req->getFlags() & FLAG_ABORT) || (mStatus == QUITTING))
#017? ??????????? {
#018? ?????????????????? req->setStatus(STATUS_ABORTED);
#019? ?????????????????? req->finishRequest(false);
#020? ?????????????????? if (req->getFlags() & FLAG_AUTO_COMPLETE)
#021? ?????????????????? {
#022? ????????????????????????? mRequestHash.erase(req);
#023? ????????????????????????? req->deleteRequest();
#024?// ????????????????????? check();
#025? ?????????????????? }
#026? ?????????????????? continue;
#027? ??????????? }
#028? ??????????? llassert_always(req->getStatus() == STATUS_QUEUED);
#029? ??????????? break;
#030? ???? }
?
設置這個消息正在處理過程中。
#031? ???? if (req)
#032? ???? {
#033? ??????????? req->setStatus(STATUS_INPROGRESS);
#034? ???? }
?
解鎖消息隊列。
#035? ???? unlockData();
#036?
#037? ???? // This is the only place we will call req->setStatus() after
#038? ???? // it has initially been seet to STATUS_QUEUED, so it is
#039? ???? // safe to access req.
?
下面開始處理獲取到的消息。
#040? ???? if (req)
#041? ???? {
?
開始調用這個消息的特別處理函數。
#042? ??????????? // process request
#043? ??????????? bool complete = req->processRequest();
#044?
?
判斷這個請求是否完成。
#045? ??????????? if (complete)
#046? ??????????? {
#047? ?????????????????? lockData();
#048? ?????????????????? req->setStatus(STATUS_COMPLETE);
#049? ?????????????????? req->finishRequest(true);
#050? ?????????????????? if (req->getFlags() & FLAG_AUTO_COMPLETE)
#051? ?????????????????? {
#052? ????????????????????????? mRequestHash.erase(req);
#053? ????????????????????????? req->deleteRequest();
#054?// ????????????????????? check();
#055? ?????????????????? }
#056? ?????????????????? unlockData();
#057? ??????????? }
#058? ??????????? else
#059? ??????????? {
#060? ?????????????????? lockData();
#061? ?????????????????? req->setStatus(STATUS_QUEUED);
#062? ?????????????????? mRequestQueue.insert(req);
#063? ?????????????????? U32 priority = req->getPriority();
#064? ?????????????????? unlockData();
#065? ?????????????????? if (priority < PRIORITY_NORMAL)
#066? ?????????????????? {
#067? ????????????????????????? ms_sleep(1); // sleep the thread a little
#068? ?????????????????? }
#069? ??????????? }
#070? ???? }
#071?
?
查看是否需要退出線程。
#072? ???? S32 res;
#073? ???? S32 pending = getPending();
#074? ???? if (pending == 0)
#075? ???? {
#076? ??????????? if (isQuitting())
#077? ??????????? {
#078? ?????????????????? res = -1; // exit thread
#079? ??????????? }
#080? ??????????? else
#081? ??????????? {
#082? ?????????????????? res = 0;
#083? ??????????? }
#084? ???? }
#085? ???? else
#086? ???? {
#087? ??????????? res = pending;
#088? ???? }
#089? ???? return res;
#090?}
#091?
?
通過在processNextRequest里調用更加具體的消息處理函數processRequest來實現各個消息處理,由于processRequest也是純虛函數,因此通過實現這個函數不同的形式,就可以實現不同的內容處理,這就是C++的多態特性。不過,要注意的是這個函數可能由多線程訪問,需要進行同步的操作。
?
?

第二人生的源碼分析(四十二)實現消息處理的線程類


更多文章、技術交流、商務合作、聯系博主

微信掃碼或搜索:z360901061

微信掃一掃加我為好友

QQ號聯系: 360901061

您的支持是博主寫作最大的動力,如果您喜歡我的文章,感覺我的文章對您有幫助,請用微信掃描下面二維碼支持博主2元、5元、10元、20元等您想捐的金額吧,狠狠點擊下面給點支持吧,站長非常感激您!手機微信長按不能支付解決辦法:請將微信支付二維碼保存到相冊,切換到微信,然后點擊微信右上角掃一掃功能,選擇支付二維碼完成支付。

【本文對您有幫助就好】

您的支持是博主寫作最大的動力,如果您喜歡我的文章,感覺我的文章對您有幫助,請用微信掃描上面二維碼支持博主2元、5元、10元、自定義金額等您想捐的金額吧,站長會非常 感謝您的哦?。?!

發表我的評論
最新評論 總共0條評論
主站蜘蛛池模板: 日韩一区二区在线观看 | 成人日韩在线 | 精品国产免费人成高清 | 69av美女| 久青草国产在视频在线观看 | 国产精品久久久久国产精品三级 | 婷婷尹人香蕉久久天堂 | 亚洲国产精品一区 | 91在线视频在线观看 | 99久久中文字幕伊人 | 亚洲欧洲日本在线 | 国产成人精品日本亚洲专一区 | 99热这里只有成人精品国产 | 国产日本亚洲欧美 | 欧美成人小视频 | 四虎国产精品免费久久久 | 欧美精品国产第一区二区 | 亚洲黄色视屏 | 99精品国产一区二区三区 | 日本一区二区视频免费播放 | 四虎色影院| 国产美女久久久久久久久久久 | 欧美一区二区三区精品 | 久草视频新 | 狠狠干人人插 | 日日操天天操夜夜操 | 国产亚洲第一 | 亚洲精品国产字幕久久不卡 | 欧美亚洲高清 | 最新亚洲情黄在线网站 | 尤物免费视频 | 色一情一欲一爱一乱 | 欧美日韩一| 最新69成人精品毛片 | 亚洲欧洲一区二区 | 久操国产视频 | 激情综合婷婷 | 国产精品国偷自产在线 | 亚洲激情在线 | 亚洲欧美小视频 | 欧美国产永久免费看片 |