WebRTC在asyncinvoker.h和asyncivoker.cpp中實現了函數的異步履行。asyncinvoker.h的注釋中給出了1個小例子,本文的學習就是從這個例子開始的。但是這個例子和單元測試代碼都只演示了如何讓1個函數在子線程中履行,以下所示。
myclass.h
#include "webrtc/base/asyncinvoker.h" #include <iostream> #include <memory> class MyClass { public: MyClass(); void OneTask(rtc::Thread *thread, int x); void AnotherAsyncTask(int x); private: std::unique_ptr<rtc::AsyncInvoker> invoker; };myclass.cpp
#include "myclass.h" MyClass::MyClass() { invoker.reset(new rtc::AsyncInvoker()); std::cout << "Main Thread ID:" << rtc::Thread::Current()->GetId() << std::endl; } void MyClass::OneTask(rtc::Thread *thread, int x) { invoker->AsyncInvoke<void>(RTC_FROM_HERE, thread, rtc::Bind(&MyClass::AnotherAsyncTask, (MyClass*)this, x)); } void MyClass::AnotherAsyncTask(int x) { std::cout << "Worker Thread ID:" << rtc::Thread::Current()->GetId() << std::endl; std::cout << "Input Value Is:" << x << std::endl; }main.cpp
#include "myclass.h" int main() { std::unique_ptr<rtc::Thread> myThread = rtc::Thread::Create(); myThread->Start(); MyClass *myClass = new MyClass; myClass->OneTask(myThread.get(), 10); Sleep(10000); return 0; }
打印結果
從上圖輸出的線程ID可以看出,函數AnotherAsyncTask是在子線程中履行的。
但是如何在子線程中調用1個函數,并讓該函數中主線程中履行呢,可以將上述代碼稍作更改,以下所示。
myclass.h
#include "webrtc/base/asyncinvoker.h" #include <iostream> #include <memory> class MyClass { public: MyClass(); void OneTask(rtc::Thread *thread, int x); void AnotherAsyncTask(int x); void myFunction(int x); private: std::unique_ptr<rtc::AsyncInvoker> invoker; rtc::Thread *mainThread; };myclass.cpp
#include "myclass.h" MyClass::MyClass() { invoker.reset(new rtc::AsyncInvoker()); std::cout << "Main Thread ID:" << rtc::Thread::Current()->GetId() << std::endl; mainThread = rtc::Thread::Current(); } void MyClass::OneTask(rtc::Thread *thread, int x) { invoker->AsyncInvoke<void>(RTC_FROM_HERE, thread, rtc::Bind(&MyClass::AnotherAsyncTask, (MyClass*)this, x)); } void MyClass::AnotherAsyncTask(int x) { std::cout << "Worker Thread ID:" << rtc::Thread::Current()->GetId() << std::endl; std::cout << "Input Value Is:" << x << std::endl; invoker->AsyncInvoke<void>(RTC_FROM_HERE, mainThread, rtc::Bind(&MyClass::myFunction, (MyClass*)this, x)); } void MyClass::myFunction(int x) { std::cout << "myFunction Thread ID:" << rtc::Thread::Current()->GetId() << std::endl; std::cout << "myFunction Value Is:" << x << std::endl; }main.cpp
#include "myclass.h" int main() { std::unique_ptr<rtc::Thread> myThread = rtc::Thread::Create(); myThread->Start(); MyClass *myClass = new MyClass; myClass->OneTask(myThread.get(), 10); Sleep(10000); return 0; }函數AnotherAsyncTask中的invoker->AsyncInvoke<void>(RTC_FROM_HERE, mainThread, rtc::Bind(&MyClass::myFunction, (MyClass*)this, x));是想在mainThread中履行myFunction,但是myFunction并未履行,打印結果仍然和上圖相同。
這里需要將main.cpp稍作修改,添加代碼實現線程的消息循環,新的main.cpp以下所示。
#include "myclass.h" int main() { std::unique_ptr<rtc::Thread> myThread = rtc::Thread::Create(); myThread->Start(); MyClass *myClass = new MyClass; myClass->OneTask(myThread.get(), 10); while (true) { rtc::Thread::Current()->ProcessMessages(0); rtc::Thread::Current()->SleepMs(1); } return 0; }打印結果以下圖所示。
從上圖輸出的線程ID可以看出,函數myFunction是在主線程中履行的。