Chromium Chronicle #1: Task Scheduling Best Practices

تیم Chrome مفتخر است که Chromium Chronicle را معرفی می کند، یک سری ماهانه که به طور خاص برای توسعه دهندگان Chromium، توسعه دهندگانی که مرورگر را می سازند، طراحی شده است.

Chromium Chronicle اساساً بر گسترش دانش فنی و بهترین روش‌ها برای نوشتن، ساخت و آزمایش Chrome متمرکز است. برنامه ما این است که موضوعات مرتبط و مفید برای توسعه دهندگان Chromium را ارائه دهیم، مانند سلامت کد، ابزارهای مفید، آزمایش واحد، دسترسی و موارد دیگر! هر مقاله توسط مهندسان کروم نوشته و ویرایش خواهد شد.

ما در مورد این سری جدید هیجان زده ایم و امیدواریم شما هم باشید! آماده شیرجه رفتن هستید؟ به قسمت اول ما در زیر نگاهی بیندازید!

بهترین شیوه های برنامه ریزی وظایف

قسمت 1: توسط گابریل شارت در مونترال، پی کیو (آوریل، 2019)
قسمت های قبلی

کد Chrome که به اجرای ناهمزمان در حین فرآیند نیاز دارد، معمولاً وظایف را به دنباله‌ها ارسال می‌کند. دنباله‌ها «رشته‌های مجازی» با مدیریت کروم هستند و ترجیح داده می‌شوند تا رشته‌های خود را ایجاد کنید . چگونه یک شی می داند که به کدام دنباله پست کند؟

نکن

الگوی قدیمی دریافت SequencedTaskRunner از سازنده است:

Foo::Foo(scoped_refptr backend_task_runner)
    : backend_task_runner_(std::move(backend_task_runner)) {}
انجام دهید

الگوی ترجیحی ایجاد یک SequencedTaskRunner مستقل است:

Foo::Foo()
    : backend_task_runner_(
          base::CreateSequencedTaskRunnerWithTraits({
              base::MayBlock(), base::TaskPriority::BEST_EFFORT})) {}

خواندن و نوشتن این آسان تر است زیرا تمام اطلاعات محلی هستند و خطر وابستگی متقابل با وظایف نامرتبط وجود ندارد.

این پارادایم در مورد آزمایش نیز بهتر است. به‌جای تزریق دستی task runners، آزمایش‌ها می‌توانند یک محیط کار کنترل‌شده را برای مدیریت وظایف Foo ایجاد کنند :

class FooTest : public testing::Test {
 public
  (...)
 protected:
  base::test::TaskEnvironment task_environment_;
  Foo foo_;
};

داشتن TaskEnvironment برای اولین بار در فیکسچر به طور طبیعی تضمین می کند که محیط کار را در طول عمر Foo مدیریت می کند. TaskEnvironment درخواست در ساخت Foo را برای ایجاد SequencedTaskRunner می گیرد و وظایف آن را تحت هر FooTest مدیریت می کند.

برای آزمایش نتیجه اجرای ناهمزمان، از پارادایم RunLoop::Run()+QuitClosure() استفاده کنید :

TEST_F(FooTest, TestAsyncWork) {
  RunLoop run_loop;
  foo_.BeginAsyncWork(run_loop.QuitClosure());
  run_loop.Run();
  EXPECT_TRUE(foo_.work_done());
}

این به RunUntilIdle ( RunUntilIdle() ترجیح داده می شود، که اگر بار کاری ناهمزمان شامل یک کار خارج از محدوده TaskEnvironment باشد، به عنوان مثال یک رویداد سیستم، می تواند پوسته پوسته شود.

می خواهید بیشتر بدانید؟ اسناد ما در مورد رشته و وظایف را بخوانید یا در مهاجرت به TaskEnvironment شرکت کنید!