Threads are very useful in application to deal with multi-thread problems, and chrome wrapped a series of excellent classes: base::Thread, MessageLoop and so on.

Thread

WARNING! SUBCLASSES MUST CALL Stop() IN THEIR DESTRUCTORS! See ~Thread().

After the thread is stopped, the destruction sequence is:

  1. Thread::CleanUp()
  2. MessageLoop::~MessageLoop
  3. MessageLoop::DestructionObserver::WillDestroyCurrentMessageLoop

Thread class

class BASE_EXPORT Thread : PlatformThread::Delegate {
 public:
  struct Options {
    Options() : message_loop_type(MessageLoop::TYPE_DEFAULT), stack_size(0) {}
    Options(MessageLoop::Type type, size_t size)
        : message_loop_type(type), stack_size(size) {}

    MessageLoop::Type message_loop_type;
    size_t stack_size;
  };

  explicit Thread(const char* name);

  // Destroys the thread, stopping it if necessary.
  //
  // NOTE: ALL SUBCLASSES OF Thread MUST CALL Stop() IN THEIR DESTRUCTORS (or
  // guarantee Stop() is explicitly called before the subclass is destroyed).
  // This is required to avoid a data race between the destructor modifying the
  // vtable, and the thread's ThreadMain calling the virtual method Run().  It
  // also ensures that the CleanUp() virtual method is called on the subclass
  // before it is destructed.
  virtual ~Thread();

#if defined(OS_WIN)
  // Causes the thread to initialize COM.
  void init_com_with_mta(bool use_mta) {
    DCHECK(!started_);
    com_status_ = use_mta ? MTA : STA;
  }
#endif

  bool Start();

  bool StartWithOptions(const Options& options);

  // Signals the thread to exit and returns once the thread has exited.
  // NOTE: If you are a consumer of Thread, it is not necessary to call this
  // before deleting your Thread objects, as the destructor will do it.
  // IF YOU ARE A SUBCLASS OF Thread, YOU MUST CALL THIS IN YOUR DESTRUCTOR.
  void Stop();

  // Returns the message loop for this thread.  Use the MessageLoop's
  // PostTask methods to execute code on the thread.  This only returns
  // non-null after a successful call to Start.  After Stop has been called,
  // this will return NULL.
  MessageLoop* message_loop() const { return message_loop_; }

  // Returns a MessageLoopProxy for this thread.  Use the MessageLoopProxy's
  // PostTask methods to execute code on the thread.  This only returns
  // non-NULL after a successful call to Start. After Stop has been called,
  // this will return NULL. Callers can hold on to this even after the thread
  // is gone.
  scoped_refptr<MessageLoopProxy> message_loop_proxy() const {
    return message_loop_ ? message_loop_->message_loop_proxy() : NULL;
  }

  // Returns the name of this thread (for display in debugger too).
  const std::string& thread_name() const { return name_; }

  // The native thread handle.
  PlatformThreadHandle thread_handle() { return thread_; }

  // The thread ID.
  PlatformThreadId thread_id() const { return thread_id_; }

  // Returns true if the thread has been started, and not yet stopped.
  bool IsRunning() const;

  //...
}

Example:

// Init thread
base::Thread* g_cache_thread = NULL;
g_cache_thread = new base::Thread("cache");
g_cache_thread->StartWithOptions(
    base::Thread::Options(MessageLoop::TYPE_IO, 0));

// Post task
g_cache_thread->message_loop_proxy()->PostTask( FROM_HERE,
    base::Bind(&ThisClass::SomeFunc, this, args) );

MessageLoop

NOTE:
MessageLoop has task reentrancy protection. This means that if a task is being processed, a second task cannot start until the first task is finished. Reentrancy can happen when processing a task, and an inner message pump is created. That inner pump then processes native messages which could implicitly start an inner task. Inner message pumps are created with dialogs (DialogBox), common dialogs (GetOpenFileName), OLE functions (DoDragDrop), printer functions (StartDoc) and many others.

Sample workaround when inner task processing is needed:

HRESULT hr;
{
  MessageLoop::ScopedNestableTaskAllower allow(MessageLoop::current());
  hr = DoDragDrop(...); // Implicitly runs a modal message loop.
}
// Process |hr| (the result returned by DoDragDrop()).

Please be SURE your task is reentrant (nestable) and all global variables are stable and accessible before calling SetNestableTasksAllowed(true).

MessageLoop class

A MessageLoop has a particular type, which indicates the set of asynchronous events it may process in addition to tasks and timers.

enum Type
{
    TYPE_DEFAULT,
    TYPE_UI,
    TYPE_IO
};

The "PostTask" family of methods call the task’s Run method asynchronously from within a message loop at some point in the future.

void PostTask(
  const tracked_objects::Location& from_here,
  const base::Closure& task);

bool TryPostTask(
  const tracked_objects::Location& from_here,
  const base::Closure& task);

void PostDelayedTask(
  const tracked_objects::Location& from_here,
  const base::Closure& task,
  base::TimeDelta delay);

void PostNonNestableTask(
  const tracked_objects::Location& from_here,
  const base::Closure& task);

void PostNonNestableDelayedTask(
  const tracked_objects::Location& from_here,
  const base::Closure& task,
  base::TimeDelta delay);

MessageLoopForUI class

MessageLoopForUI extends MessageLoop with methods that are particular to a MessageLoop instantiated with TYPE_UI.

This class is typically used like so:
`MessageLoopForUI::current()->…call some method…`

class BASE_EXPORT MessageLoopForUI : public MessageLoop {
 public:
  typedef base::MessagePumpForUI::MessageFilter MessageFilter;

  MessageLoopForUI() : MessageLoop(TYPE_UI) {
  }

  // Returns the MessageLoopForUI of the current thread.
  static MessageLoopForUI* current() {
    MessageLoop* loop = MessageLoop::current();
    DCHECK(loop);
    DCHECK_EQ(MessageLoop::TYPE_UI, loop->type());
    return static_cast<MessageLoopForUI*>(loop);
  }

  void DidProcessMessage(const MSG& message);


  void AddObserver(Observer* observer);
  void RemoveObserver(Observer* observer);

  // Plese see MessagePumpForUI for definitions of this method.
  void SetMessageFilter(scoped_ptr<MessageFilter> message_filter) {
    pump_ui()->SetMessageFilter(message_filter.Pass());
  }

 protected:
  base::MessagePumpForUI* pump_ui() {
    return static_cast<base::MessagePumpForUI*>(pump_.get());
  }
};

MessageLoopForIO class

MessageLoopForIO extends MessageLoop with methods that are particular to a MessageLoop instantiated with TYPE_IO.

This class is typically used like so: MessageLoopForIO::current()->…call some method…

class BASE_EXPORT MessageLoopForIO : public MessageLoop {
 public:
  typedef base::MessagePumpForIO::IOHandler IOHandler;
  typedef base::MessagePumpForIO::IOContext IOContext;
  typedef base::MessagePumpForIO::IOObserver IOObserver;

  MessageLoopForIO() : MessageLoop(TYPE_IO) {
  }

  // Returns the MessageLoopForIO of the current thread.
  static MessageLoopForIO* current() {
    MessageLoop* loop = MessageLoop::current();
    DCHECK_EQ(MessageLoop::TYPE_IO, loop->type());
    return static_cast<MessageLoopForIO*>(loop);
  }

  void AddIOObserver(IOObserver* io_observer) {
    pump_io()->AddIOObserver(io_observer);
  }

  void RemoveIOObserver(IOObserver* io_observer) {
    pump_io()->RemoveIOObserver(io_observer);
  }

  // Please see MessagePumpWin for definitions of these methods.
  void RegisterIOHandler(HANDLE file, IOHandler* handler);
  bool RegisterJobObject(HANDLE job, IOHandler* handler);
  bool WaitForIOCompletion(DWORD timeout, IOHandler* filter);

 protected:
  base::MessagePumpForIO* pump_io() {
    return static_cast<base::MessagePumpForIO*>(pump_.get());
  }
};

MessageLoopProxy

This class provides a thread-safe refcounted interface to the Post* methods of a message loop. This class can outlive the target message loop.

So, to access them, you can use any of the following:

Samples:

#include "base/memory/weak_ptr.h"
#include "base/threading/thread.h"
#include "base/bind.h"

struct DataBuffer 
  : base::RefCountedThreadSafe<DataBuffer>
{
  std::string data_;
};

class ThreadTest 
  : public base::RefCountedThreadSafe<ThreadTest> {
public:
  ThreadTest() 
    : worker_thread_("worker") 
  {
      base::Thread::Options options;
      options.message_loop_type = base::MessageLoop::TYPE_DEFAULT;
      worker_thread_.StartWithOptions( options );
  }

  void work() {
    scoped_refptr<DataBuffer> buf = new DataBuffer;

    // PostTaskAndReply need to be called on thread with a base::MessageLoop
    worker_thread_.message_loop_proxy()->PostTaskAndReply(FROM_HERE,
      base::Bind(&ThreadTest::DoTask, make_scoped_refptr(this), buf),
      base::Bind(&ThreadTest::OnReply, make_scoped_refptr(this), buf) );
  }


private:
  void DoTask( scoped_refptr<DataBuffer> buf ) {
    // Prepare data
    if ( buf ) {
      buf->data_ = "hello";
    }
  }

  void OnReply( scoped_refptr<DataBuffer> buf ) {
    // Deal with data
    buf->data_;
  }

private:
  base::Thread worker_thread_;
};

// global
scoped_refptr<ThreadTest> g_test;

void ThreadTestFunc() {
  g_test = new ThreadTest;
  g_test->work();
}