Chromium中的线程同步

1.Lock

线程互斥锁,使用方法:

Lock g_lock;
..
{
    AutoLock scope_lock(g_lock);
}

AutoLock的构造函数和析构函数里会调用Lock的acquire和release

  explicit AutoLock(Lock& lock) : lock_(lock) {
    lock_.Acquire();
  }

  ~AutoLock() {
    lock_.AssertAcquired();
    lock_.Release();
  }

Lock的acquire和release方法会调用LockImpl的Lock和Unlock方法,LockImpl由各个平台实现

  void Acquire() { lock_.Lock(); }
  void Release() { lock_.Unlock(); }

  internal::LockImpl lock_;

LockImpl在posix上的实现:

LockImpl::LockImpl() {
  pthread_mutexattr_t mta;
  int rv = pthread_mutexattr_init(&mta);
  DCHECK_EQ(rv, 0) << ". " << strerror(rv);
......
  rv = pthread_mutex_init(&native_handle_, &mta);
  DCHECK_EQ(rv, 0) << ". " << strerror(rv);
  rv = pthread_mutexattr_destroy(&mta);
  DCHECK_EQ(rv, 0) << ". " << strerror(rv);
}
void LockImpl::Lock() {
  int rv = pthread_mutex_lock(&native_handle_);
  DCHECK_EQ(rv, 0) << ". " << strerror(rv);
}

void LockImpl::Unlock() {
  int rv = pthread_mutex_unlock(&native_handle_);
  DCHECK_EQ(rv, 0) << ". " << strerror(rv);
}

posix上的LockImpl使用pthread_mutex来实现

2. AtomicFlag

多线程安全的一个flag,有两个方法,Set和IsSet。

  void Set(); //设置标志

  bool IsSet() const; //检查标志是否设置

3.ConditionVariable

接口:

 ConditionVariable(Lock* user_lock);
  void Wait();
  void TimedWait(const TimeDelta& max_time);

  // signal all waiting thread  
  void Broadcast();
  // Signal() revives one waiting thread.
  void Signal();

wait:

  Lock lock;
  ConditionVariable cv(&lock);

  lock.Acquire();
  cv.Wait(); //wait退出后会自动获取锁

signal


//signal之前,获取锁
lock.Acquire()

cv.Signal()

4.Spin wait

用法:

SPIN_FOR_1_SECOND_OR_UNTIL_TRUE(express);
SPIN_FOR_TIMEDELTA_OR_UNTIL_TRUE(delta, expression)

宏,通过while循环等待,直到expression为真,或者1s(delta)超时

5. WaitableEvent

WaitableEvent(ResetPolicy reset_policy, InitialState initial_state);

  // Put the event in the un-signaled state.
  void Reset();

  // Put the event in the signaled state.  Causing any thread blocked on Wait
  // to be woken up.
  void Signal();

  // Returns true if the event is in the signaled state, else false.  If this
  // is not a manual reset event, then this test will cause a reset.
  bool IsSignaled();

  // Wait indefinitely for the event to be signaled. Wait's return "happens
  // after" |Signal| has completed. 
  void Wait();

  // Wait up until wait_delta has passed for the event to be signaled.  Returns
  // true if the event was signaled.
  //
  // TimedWait can synchronise its own destruction like |Wait|.
  bool TimedWait(const TimeDelta& wait_delta);

  // Wait up until end_time deadline has passed for the event to be signaled.
  // Return true if the event was signaled.
  //
  // TimedWaitUntil can synchronise its own destruction like |Wait|.
  bool TimedWaitUntil(const TimeTicks& end_time);

WaitableEvent使用WaitableEventKernel来实现。

  struct WaitableEventKernel :
      public RefCountedThreadSafe {
   public:
    WaitableEventKernel(ResetPolicy reset_policy, InitialState initial_state);

    bool Dequeue(Waiter* waiter, void* tag);

    base::Lock lock_;
    const bool manual_reset_;
    bool signaled_;
    std::list waiters_;

   private:
    friend class RefCountedThreadSafe;
    ~WaitableEventKernel();
  };

WaitableEvent在posix平台上的实现

void WaitableEvent::Wait() {
  bool result = TimedWaitUntil(TimeTicks::Max());
  DCHECK(result) << "TimedWait() should never fail with infinite timeout";
}

bool WaitableEvent::TimedWait(const TimeDelta& wait_delta) {
  // TimeTicks takes care of overflow including the cases when wait_delta
  // is a maximum value.
  return TimedWaitUntil(TimeTicks::Now() + wait_delta);
}

bool WaitableEvent::TimedWaitUntil(const TimeTicks& end_time) {
  const bool finite_time = !end_time.is_max();

  kernel_->lock_.Acquire();
  if (kernel_->signaled_) {
    if (!kernel_->manual_reset_) {
      // In this case we were signaled when we had no waiters. Now that
      // someone has waited upon us, we can automatically reset.
      kernel_->signaled_ = false;
    }

    kernel_->lock_.Release();
    return true;
  }

  SyncWaiter sw;
  sw.lock()->Acquire();

  Enqueue(&sw);
  kernel_->lock_.Release();
  // We are violating locking order here by holding the SyncWaiter lock but not
  // the WaitableEvent lock. However, this is safe because we don't lock @lock_
  // again before unlocking it.

  for (;;) {
    const TimeTicks current_time(TimeTicks::Now());

    if (sw.fired() || (finite_time && current_time >= end_time)) {
      const bool return_value = sw.fired();

      // We can't acquire @lock_ before releasing the SyncWaiter lock (because
      // of locking order), however, in between the two a signal could be fired
      // and @sw would accept it, however we will still return false, so the
      // signal would be lost on an auto-reset WaitableEvent. Thus we call
      // Disable which makes sw::Fire return false.
      sw.Disable();
      sw.lock()->Release();

      // This is a bug that has been enshrined in the interface of
      // WaitableEvent now: |Dequeue| is called even when |sw.fired()| is true,
      // even though it'll always return false in that case. However, taking
      // the lock ensures that |Signal| has completed before we return and
      // means that a WaitableEvent can synchronise its own destruction.
      kernel_->lock_.Acquire();
      kernel_->Dequeue(&sw, &sw);
      kernel_->lock_.Release();

      return return_value;
    }

    if (finite_time) {
      const TimeDelta max_wait(end_time - current_time);
      sw.cv()->TimedWait(max_wait);
    } else {
      sw.cv()->Wait();
    }
  }
}

各种版本的Wait都调用到了TimedWaitUntil,在TimedWaitUntil里,先判断是否signal了,如果signal了,则返回true。

如果需要wait,则创建一个SyncWaiter,加入到kernel的waiter列表里。

void WaitableEvent::Reset() {
  base::AutoLock locked(kernel_->lock_);
  kernel_->signaled_ = false;
}

void WaitableEvent::Signal() {
  base::AutoLock locked(kernel_->lock_);

  if (kernel_->signaled_)
    return;

  if (kernel_->manual_reset_) {
    SignalAll();
    kernel_->signaled_ = true;
  } else {
    // In the case of auto reset, if no waiters were woken, we remain
    // signaled.
    if (!SignalOne())
      kernel_->signaled_ = true;
  }
}

bool WaitableEvent::IsSignaled() {
  base::AutoLock locked(kernel_->lock_);

  const bool result = kernel_->signaled_;
  if (result && !kernel_->manual_reset_)
    kernel_->signaled_ = false;
  return result;
}

当signal的时候,如果reset的模式是manual的,那么SignalAll,同时将kernel_->signaled_置为true,如果reset模式是Auto,则SignalOne,如果SingalOne返回True,则将kernel_->signaled_置为true。

bool WaitableEvent::SignalAll() {
  bool signaled_at_least_one = false;

  for (std::list::iterator
       i = kernel_->waiters_.begin(); i != kernel_->waiters_.end(); ++i) {
    if ((*i)->Fire(this))
      signaled_at_least_one = true;
  }

  kernel_->waiters_.clear();
  return signaled_at_least_one;
}

bool WaitableEvent::SignalOne() {
  for (;;) {
    if (kernel_->waiters_.empty())
      return false;

    const bool r = (*kernel_->waiters_.begin())->Fire(this);
    kernel_->waiters_.pop_front();
    if (r)
      return true;
  }
}

你可能感兴趣的:(Chromium中的线程同步)