webrtc AsyncInvoker 和 rtc::Thread::Invoke 的区别的坑

webrtc 中 AsyncInvoker 和 rtc::Thread::Invoke 都可以用于实现了函数的异步执行。具体使用方法去啃代码就可以知道。

下面说一下两者的差别:

AsyncInvoker: 

Invokes function objects (aka functors) asynchronously on a Thread, and
owns the lifetime of calls (ie, when this object is destroyed, calls in
flight are cancelled). AsyncInvoker can optionally execute a user-specified
function when the asynchronous call is complete, or operates in
fire-and-forget mode otherwise.

AsyncInvoker does not own the thread it calls functors on.

A note about async calls and object lifetimes: users should
be mindful of object lifetimes when calling functions asynchronously and
ensure objects used by the function _cannot_ be deleted between the
invocation and execution of the functor. AsyncInvoker is designed to
help: any calls in flight will be cancelled when the AsyncInvoker used to
make the call is destructed, and any calls executing will be allowed to
complete before AsyncInvoker destructs.

The easiest way to ensure lifetimes are handled correctly is to create a
class that owns the Thread and AsyncInvoker objects, and then call its
methods asynchronously as needed.

rtc::Thread::Invoke:

Convenience method to invoke a functor on another thread.  Caller must
provide the |ReturnT| template argument, which cannot (easily) be deduced.
Uses Send() internally, which blocks the current thread until execution
is complete.

我在使用过程中使用出现了如下情况:

#include "webrtc/base/asyncinvoker.h"
#include "webrtc/base/thread.h"
#include "webrtc/base/bind.h"


class MyClass {
public:
  MyClass(): workThread_(new rtc::Thread()) {
    workThread_->Start();}
  ~MyClass() {workThread_->Stop();workThread_ = nullptr;  } 
  void MethodA() {
    invoker.AsyncInvoke(RTC_FROM_HERE, workThread_, rtc::Bind(&MyClass::MethodA, this));
    // doWork  
  }  
  void MethodB() {
    invoker.AsyncInvoke(RTC_FROM_HERE, workThread_, rtc::Bind(&MyClass::MethodB, this));
    // doWork  } 
private: 
 rtc::Thread *workThread_; 
 rtc::AsyncInvoker invoker;
};

在MyClass 对象销毁时,其析构函数会在workThread_中销毁。这时workThread 的销毁就会在workThread线程中执行,就会出现错误。

究其原因应该是:invoker 在执行过程中会获得当前object的生命周期管理权。所以此时应该用thread::Invoker() 代替。

你可能感兴趣的:(音视频)