设为首页 加入收藏

TOP

深入V8引擎-默认Platform之mac篇(2)(三)
2019-09-17 19:10:12 】 浏览:92
Tags:深入 引擎 默认 Platform mac篇
么设置线程名字我也不太想知道。

  第二步的方法名就是运行线程的任务,调用链比较长,会来回在几个类之间穿梭,调用各自属性的方法。

// 3-7
void NotifyStartedAndRun() {
  if (start_semaphore_) start_semaphore_->Signal();
  // 3-8
  Run();
}

// 3-8
void DefaultWorkerThreadsTaskRunner::WorkerThread::Run() {
  runner_->single_worker_thread_id_.store(base::OS::GetCurrentThreadId(), std::memory_order_relaxed);
  // 3-9
  while (std::unique_ptr<Task> task = runner_->GetNext()) {
    // 每一个task会实现自己的run函数
    task->Run();
  }
}

// 3-9
std::unique_ptr<Task> DefaultWorkerThreadsTaskRunner::GetNext() {
  // 3-10
  return queue_.GetNext();
}

  不理清楚,这个地方真的很麻烦,绕得很,可以看顶部的继承图。总之,最后调用的是DefaultWorkerThreadsTaskRunner类上一个类型为DelayedTaskQueue类的GetNext方法,返回类型是Task类,V8只是简单定义了一个基类,实际运行时的task都需要继承这个类并实现其Run方法以便线程执行。

  最后的最后,GetNext的逻辑其实可以参考libuv的逻辑,机制都大同小异,方法的源码如下。

// 3-10
std::unique_ptr<Task> DelayedTaskQueue::GetNext() {
  base::MutexGuard guard(&lock_);
  for (;;) {
    /**
     * 这一片内容完全可以参考libuv事件轮询的前两步
     * 1、从DelayQueue队列中依次取出超过指定时间的task
     * 2、将所有超时的task放到task_queue_队列中
     * 3、从task_queue_中将task依次取出并返回
     * 4、外部会调用task的Run方法并重复调用该函数
    */
    double now = MonotonicallyIncreasingTime();
    std::unique_ptr<Task> task = PopTaskFromDelayedQueue(now);
    while (task) {
      task_queue_.push(std::move(task));
      task = PopTaskFromDelayedQueue(now);
    }
    if (!task_queue_.empty()) {
      std::unique_ptr<Task> result = std::move(task_queue_.front());
      task_queue_.pop();
      return result;
    }

    if (terminated_) {
      queues_condition_var_.NotifyAll();
      return nullptr;
    }
    /**
     * 1、当task_queue_队列没有task需要处理 但是delay_task_queue_有待处理task
     * 这里会计算当前队列中延迟task中最近的触发时间 等待对应的时间再次触发
     * 2、当两个队列都没有需要的事件
     * 线程会直接休眠等待唤醒
    */
    if (task_queue_.empty() && !delayed_task_queue_.empty()) {
      double wait_in_seconds = delayed_task_queue_.begin()->first - now;
      base::TimeDelta wait_delta = base::TimeDelta::FromMicroseconds(base::TimeConstants::kMicrosecondsPerSecond * wait_in_seconds);

      bool notified = queues_condition_var_.WaitFor(&lock_, wait_delta);
      USE(notified);
    } else {
      queues_condition_var_.Wait(&lock_);
    }
  }
}

  哎……V8引擎不过如此。

首页 上一页 1 2 3 下一页 尾页 3/3/3
】【打印繁体】【投稿】【收藏】 【推荐】【举报】【评论】 【关闭】 【返回顶部
上一篇VUE中全局变量的定义和使用 下一篇JavaScript Timing 事件及两种时..

最新文章

热门文章

Hot 文章

Python

C 语言

C++基础

大数据基础

linux编程基础

C/C++面试题目