Google開源框架libjingle使用分析
阿新 • • 發佈:2019-02-08
執行緒模型簡介
傳統的回撥機制,可控性差、容易導致死鎖等問題。本模組採用非同步任務機制,通過command模式,可以很好的進行多執行緒的協作,避免使用共享變數、加鎖,有效的防止死鎖與其他多執行緒安全問題。
實現上使用了 libjingle 庫。(注:原來使用了 chrome base 的執行緒庫,兩者實現原理一致,但 libjingle 使用上方便一些。)
把要非同步執行的任務資訊封裝在 Message 資料結構中,Post 或 PostDelay 到相應的執行緒去執行。在該執行緒執行完之後,如果需要通知發起執行緒,則再 Post 回原來的執行緒。每個執行緒都有自己的訊息佇列,執行緒不停地從佇列中取出 Message 執行相應的任務。
多執行緒之間資料共享:
thread_A (data_A),thread_B(data_B)
從thread_A轉到thread_B,在thread_A中呼叫:
thread_B->post(handler,msg_id,new data_B(data_A,len))
根據data_A,拷貝一份資料data_B,任務執行完畢後,釋放拷貝資料data_B
執行緒模型:
class MessageHandler { public: virtual ~MessageHandler(); virtual void OnMessage(Message* msg) = 0; protected: MessageHandler() {} private: DISALLOW_COPY_AND_ASSIGN(MessageHandler); };
class MessageData {
public:
MessageData() {}
virtual ~MessageData() {}
};
struct Message {
MessageHandler *phandler;
uint32 message_id;
MessageData *pdata;
uint32 ts_sensitive;
};
typedef std::list<Message> MessageList;
class MessageQueue { virtual bool Get(Message *pmsg, int cmsWait = kForever, bool process_io = true) { *pmsg = msgq_.front(); msgq_.pop_front(); } virtual void Post(MessageHandler *phandler, uint32 id = 0, MessageData *pdata = NULL, bool time_sensitive = false) { Message msg; msg.phandler = phandler; msg.message_id = id; msg.pdata = pdata; msgq_.push_back(msg); } virtual void Dispatch(Message *pmsg) { pmsg->phandler->OnMessage(pmsg); } protected: MessageList msgq_; }
class Thread : public MessageQueue {
public:
bool Start(Runnable* runnable = NULL) {
PreRun();
}
void Run() {
ProcessMessages(kForever);
}
bool ProcessMessages(int cms) {
Message msg;
if (!Get(&msg, cmsNext))
return !IsQuitting();
Dispatch(&msg);
}
private:
static void *PreRun(void *pv) {
Run();
}
#ifdef POSIX
pthread_t thread_;
#endif
#ifdef WIN32
HANDLE thread_;
DWORD thread_id_;
#endif
};