Chromium Chronicle #1: Praktik Terbaik Penjadwalan Tugas

Tim Chrome dengan bangga memperkenalkan Chromium Chronicle, seri yang khusus ditujukan untuk developer Chromium, developer yang browser.

Chromium Chronicle akan berfokus terutama pada penyebaran pengetahuan teknis dan praktik terbaik untuk menulis, membangun, dan menguji Chrome. Rencana kami adalah menampilkan topik yang relevan dan berguna bagi developer Chromium, seperti kode kesehatan, alat yang bermanfaat, pengujian unit, aksesibilitas, dan banyak lagi! Setiap artikel akan ditulis dan diedit oleh engineer Chrome.

Kami sangat menantikan seri baru ini, dan semoga Anda juga demikian! Siap untuk memulai? Lihat episode pertama kami di bawah ini.

Praktik Terbaik Penjadwalan Tugas

Episode 1: oleh Gabriel Charette di Montréal, PQ (April, 2019)
Episode sebelumnya

Kode Chrome yang memerlukan eksekusi asinkron dalam proses biasanya memposting tugas urutan. Urutan adalah "rangkaian virtual" yang dikelola Chrome dan merupakan lebih disarankan untuk membuat rangkaian pesan Anda sendiri. Bagaimana suatu objek tahu ke urutan mana untuk memposting?

Larangan

Paradigma lamanya adalah menerima SequencedTaskRunner dari kreator:

Foo::Foo(scoped_refptr backend_task_runner)
    : backend_task_runner_(std::move(backend_task_runner)) {}
Anjuran

Paradigma yang disukai adalah membuat SequencedTaskRunner independen:

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

Ini lebih mudah dibaca dan ditulis karena semua informasi bersifat lokal dan ada tidak ada risiko inter-dependensi dengan tugas-tugas yang tidak terkait.

Paradigma ini juga lebih baik dalam hal pengujian. Daripada memasukkan menjalankan task runner secara manual, pengujian dapat membuat instance lingkungan tugas terkontrol untuk mengelola tugas Foo:

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

Memiliki TaskEnvironment pertama di perlengkapan secara alami akan memastikannya mengelola lingkungan tugas sepanjang masa hidup Foo. TaskEnvironment akan menangkap request-on-konstruksi Foo untuk membuat SequencedTaskRunner dan akan mengelola tugasnya di bawah setiap FooTest.

Untuk menguji hasil eksekusi asinkron, gunakan metode Paradigma RunLoop::Run()+QuitClosure():

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

Hal ini lebih disukai daripada RunBeforeIdle(), yang bisa tidak stabil jika model workload melibatkan tugas di luar cakupan TaskEnvironment, mis. peristiwa sistem, jadi gunakan RunUntilIdle() dengan hati-hati.

Ingin mempelajari lebih lanjut? Baca dokumentasi kami tentang threading dan tugas atau ikuti proses migrasi ke TaskEnvironment.