Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(15)

Side by Side Diff: docs/threading_and_tasks.md

Issue 2875653003: Add "Threading and Tasks in Chrome" documentation. (Closed)
Patch Set: Created 3 years, 7 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « docs/README.md ('k') | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
(Empty)
1 # Threading and Tasks in Chrome
2
3 [TOC]
4
5 ## Overview
6
7 ### Threads
8
9 Every Chrome process has
10
11 * a main thread
12 * in the browser process: updates the UI
13 * in renderer processes: runs most of Blink
14 * an IO thread
15 * in the browser process: handles IPCs and network requests
16 * in renderer processes: handles IPCs
17 * a few more special-purpose threads
18 * and a pool of general-purpose threads
19
20 Most threads have a loop that gets tasks from a queue and runs them (the queue
21 may be shared between multiple threads).
22
23 ### Tasks
24
25 A task is a `base::OnceClosure` added to a queue for asynchronous execution.
26
27 A `base::OnceClosure` stores a function pointer and arguments. It has a `Run()`
28 method that invokes the function pointer using the bound arguments. It is
29 created using `base::BindOnce`. (ref. [Callback<> and Bind()
30 documentation](callback.md)).
31
32 ```
33 void TaskA() {}
34 void TaskB(int v) {}
35
36 auto task_a = base::BindOnce(&TaskA);
37 auto task_b = base::BindOnce(&TaskB, 42);
38 ```
39
40 A group of tasks can be executed in one of the following ways:
41
42 * [Parallel](#Posting-a-Parallel-Task): No task execution ordering, possibly all
43 at once on any thread
44 * [Sequenced](#Posting-a-Sequenced-Task): Tasks executed in posting order, one
45 at a time on any thread.
46 * [Single Threaded](#Posting-Multiple-Tasks-to-the-Same-Thread): Tasks executed
47 in posting order, one at a time on a single thread.
48 * [COM Single Threaded](#Posting-Tasks-to-a-COM-Single-Thread-Apartment-STA_T hread-Windows_):
49 A variant of single threaded with COM initialized.
50
51 The discussion below covers all of these ways to execute tasks.
52
53 ## Posting a Parallel Task
54
55 ### Direct Posting to the Task Scheduler
56
57 A task that can run on any thread and doesn’t have ordering or mutual exclusion
58 requirements with other tasks should be posted using one of the
59 `base::PostTask*()` functions defined in
60 [`base/task_scheduler/post_task.h`](https://cs.chromium.org/chromium/src/base/ta sk_scheduler/post_task.h).
61
62 ```cpp
63 base::PostTask(FROM_HERE, base::BindOnce(&Task));
64 ```
65
66 This posts tasks with default traits.
67
68 The `base::PostTask*WithTraits()` functions allow the caller to provide
69 additional details about the task via TaskTraits (ref.
70 [Annotating Tasks with TaskTraits](#Annotating-Tasks-with-TaskTraits)).
71
72 ```cpp
73 base::PostTaskWithTraits(
74 FROM_HERE, {base::TaskPriority::BACKGROUND, MayBlock()},
75 base::BindOnce(&Task));
76 ```
77
78 ## Posting via a TaskRunner
79
80 A parallel
81 [`TaskRunner`](https://cs.chromium.org/chromium/src/base/task_runner.h) is an
82 alternative to calling `base::PostTask*()` directly. This is mainly useful when
83 it isn’t known in advance whether tasks will be posted in parallel, in sequence,
84 or to a single-thread (ref. [Posting a Sequenced Task](#Posting-a-Sequenced-
85 Task), [Posting Multiple Tasks to the Same Thread](#Posting-Multiple-Tasks-to-
86 the-Same-Thread)). Since `TaskRunner` is the base class of `SequencedTaskRunner`
87 and `SingleThreadTaskRunner`, a `scoped_refptr<TaskRunner>` member can hold a
88 `TaskRunner`, a `SequencedTaskRunner` or a `SingleThreadTaskRunner`.
89
90 ```cpp
91 class A {
92 public:
93 A() = default;
94
95 void set_task_runner_for_testing(
96 scoped_refptr<base::TaskRunner> task_runner) {
97 task_runner_ = std::move(task_runner);
98 }
99
100 void DoSomething() {
101 // In production, A is always posted in parallel. In test, it is posted to
102 // the TaskRunner provided via set_task_runner_for_testing().
103 task_runner_->PostTask(FROM_HERE, base::BindOnce(&A));
104 }
105
106 private:
107 scoped_refptr<base::TaskRunner> task_runner_ =
108 base::CreateTaskRunnerWithTraits({base::TaskPriority::USER_VISIBLE});
109 };
110 ```
111
112 Unless a test needs to control precisely how tasks are executed, it is preferred
113 to call `base::PostTask*()` directly (ref. [Testing](#Testing) for less invasive
114 ways of controlling tasks in tests).
115
116 ## Posting a Sequenced Task
117
118 A sequence is a set of tasks that run one at a time in posting order (not
119 necessarily on the same thread). To post tasks as part of a sequence, use a
120 [`SequencedTaskRunner`](https://cs.chromium.org/chromium/src/base/sequenced_tas k_runner.h).
121
122 ### Posting to a New Sequence
123
124 A `SequencedTaskRunner` can be created by
125 `base::CreateSequencedTaskRunnerWithTraits()`.
126
127 ```cpp
128 scoped_refptr<SequencedTaskRunner> sequenced_task_runner =
129 base::CreateSequencedTaskRunnerWithTraits(...);
130
131 // TaskB runs after TaskA completes.
132 sequenced_task_runner->PostTask(FROM_HERE, base::BindOnce(&TaskA));
133 sequenced_task_runner->PostTask(FROM_HERE, base::BindOnce(&TaskB));
134 ```
135
136 ### Posting to the Current Sequence
137
138 The `SequencedTaskRunner` to which the current task was posted can be obtained
139 via
140 [`SequencedTaskRunnerHandle::Get()`](https://cs.chromium.org/chromium/src/base/t hreading/sequenced_task_runner_handle.h).
141
142 *** note
143 **NOTE:** it is invalid to call `SequencedTaskRunnerHandle::Get()` from a
144 parallel task, but it is valid from a single-threaded task (a
145 `SingleThreadTaskRunner` is a `SequencedTaskRunner`).
146 ***
147
148 ```cpp
149 // The task will run after any task that has already been posted
150 // to the SequencedTaskRunner to which the current task was posted
151 // (in particular, it will run after the current task completes).
152 // It is also guaranteed that it won’t run concurrently with any
153 // task posted to that SequencedTaskRunner.
154 base::SequencedTaskRunnerHandle::Get()->
155 PostTask(FROM_HERE, base::BindOnce(&Task));
156 ```
157
158 ## Using Sequences Instead of Locks
159
160 Usage of locks is discouraged in Chrome. Sequences inherently provide
161 thread-safety. Prefer classes that are always accessed from the same sequence to
162 managing your own thread-safety with locks.
163
164 ```cpp
165 class A {
166 public:
167 A() {
168 // Do not require accesses to be on the creation sequence.
169 sequence_checker_.DetachFromSequence();
170 }
171
172 void AddValue(int v) {
173 // Check that all accesses are on the same sequence.
174 DCHECK(sequence_checker_.CalledOnValidSequence());
175 values_.push_back(v);
176 }
177
178 private:
179 base::SequenceChecker sequence_checker_;
180
181 // No lock required, because all accesses are on the
182 // same sequence.
183 std::vector<int> values_;
184 };
185
186 A a;
187 scoped_refptr<SequencedTaskRunner> task_runner_for_a = ...;
188 task_runner->PostTask(FROM_HERE,
189 base::BindOnce(&A::AddValue, base::Unretained(&a)));
190 task_runner->PostTask(FROM_HERE,
191 base::BindOnce(&A::AddValue, base::Unretained(&a)));
192
193 // Access from a different sequence causes a DCHECK failure.
194 scoped_refptr<SequencedTaskRunner> other_task_runner = ...;
195 other_task_runner->PostTask(FROM_HERE,
196 base::BindOnce(&A::AddValue, base::Unretained(&a)));
197 ```
198
199 ## Posting Multiple Tasks to the Same Thread
200
201 If multiple tasks need to run on the same thread, post them to a
202 [`SingleThreadTaskRunner`](https://cs.chromium.org/chromium/src/base/single_thre ad_task_runner.h).
203 All tasks posted to the same `SingleThreadTaskRunner` run on the same thread in
204 posting order.
205
206 ### Posting to the Main Thread or to the IO Thread in the Browser Process
207
208 To post tasks to the main thread or to the IO thread, get the appropriate
209 SingleThreadTaskRunner using `content::BrowserThread::GetTaskRunnerForThread`.
210
211 ```cpp
212 content::BrowserThread::GetTaskRunnerForThread(content::BrowserThread::UI)
213 ->PostTask(FROM_HERE, ...);
214
215 content::BrowserThread::GetTaskRunnerForThread(content::BrowserThread::IO)
216 ->PostTask(FROM_HERE, ...);
217 ```
218
219 The main thread and the IO thread are already super busy. Therefore, prefer
220 posting to a general purpose thread when possible (ref. [Posting a Parallel
221 Task](#Posting-a-Parallel-Task), [Posting a Sequenced task](#Posting-a
222 -Sequenced-Task)). Good reasons to post to the main thread are to update the UI
223 or access objects that are bound to it (e.g. `Profile`). A good reason to post
224 to the IO thread is to access the internals of components that are bound to it
225 (e.g. IPCs, network). Note: It is not necessary to have an explicit post task to
226 the IO thread to send/receive an IPC or send/receive data on the network.
227
228 ### Posting to the Main Thread in a Renderer Process
229 TODO
230
231 ### Posting to a Custom SingleThreadTaskRunner
232
233 If multiple tasks need to run on the same thread and that thread doesn’t have to
234 be the main thread or the IO thread, post them to a `SingleThreadTaskRunner`
235 created by `base::CreateSingleThreadTaskRunnerWithTraits`.
236
237 ```cpp
238 scoped_refptr<SequencedTaskRunner> single_thread_task_runner =
239 base::CreateSingleThreadTaskRunnerWithTraits(...);
240
241 // TaskB runs after TaskA completes. Both tasks run on the same thread.
242 single_thread_task_runner->PostTask(FROM_HERE, base::BindOnce(&TaskA));
243 single_thread_task_runner->PostTask(FROM_HERE, base::BindOnce(&TaskB));
244 ```
245
246 *** note
247 **IMPORTANT:** You should rarely need this, most classes in Chromium require
248 thread-safety (which sequences provide) not thread-affinity. If an API you’re
249 using is incorrectly thread-affine (i.e. using
250 [`base::ThreadChecker`](https://cs.chromium.org/chromium/src/base/threading/thre ad_checker.h)
251 when it’s merely thread-unsafe and should use
252 [`base::SequenceChecker`](https://cs.chromium.org/chromium/src/base/sequence_che cker.h)),
253 please consider fixing it instead of making things worse by also making your API thread-affine.
254 ***
255
256 ### Posting to the Current Thread
257
258 *** note
259 **IMPORTANT:** To post a task that needs mutual exclusion with the current
260 sequence of tasks but doesn’t absolutely need to run on the current thread, use
261 `SequencedTaskRunnerHandle::Get()` instead of `ThreadTaskRunnerHandle::Get()`
262 (ref. [Posting to the Current Sequence](#Posting-to-the-Current-Sequence)). That
263 will better document the requirements of the posted task. In a single-thread
264 task, `SequencedTaskRunnerHandle::Get()` is equivalent to
265 `ThreadTaskRunnerHandle::Get()`.
266 ***
267
268 To post a task to the current thread, use [`ThreadTaskRunnerHandle`](https://cs. chromium.org/chromium/src/base/threading/thread_task_runner_handle.h).
269
270 ```cpp
271 // The task will run on the current thread in the future.
272 base::ThreadTaskRunnerHandle::Get()->PostTask(
273 FROM_HERE, base::BindOnce(&Task));
274 ```
275
276 *** note
277 **NOTE:** It is invalid to call `ThreadTaskRunnerHandle::Get()` from a parallel
278 or a sequenced task.
279 ***
280
281 ## Posting Tasks to a COM Single-Thread Apartment (STA) Thread (Windows)
282
283 Tasks that need to run on a COM Single-Thread Apartment (STA) thread must be
284 posted to a `SingleThreadTaskRunner` returned by
285 `CreateCOMSTATaskRunnerWithTraits()`. As mentioned in [Posting Multiple Tasks to
286 the Same Thread](#Posting-Multiple-Tasks-to-the-Same-Thread), all tasks posted
287 to the same `SingleThreadTaskRunner` run on the same thread in posting order.
288
289 ```cpp
290 // Task(A|B|C)UsingCOMSTA will run on the same COM STA thread.
291
292 void TaskAUsingCOMSTA() {
293 // [ This runs on a COM STA thread. ]
294
295 // Make COM STA calls.
296 // ...
297
298 // Post another task to the current COM STA thread.
299 base::ThreadTaskRunnerHandle::Get()->PostTask(
300 FROM_HERE, base::BindOnce(&TaskCUsingCOMSTA));
301 }
302 void TaskBUsingCOMSTA() { }
303 void TaskCUsingCOMSTA() { }
304
305 auto com_sta_task_runner = base::CreateCOMSTATaskRunnerWithTraits(...);
306 com_sta_task_runner->PostTask(FROM_HERE, base::BindOnce(&TaskAUsingCOMSTA));
307 com_sta_task_runner->PostTask(FROM_HERE, base::BindOnce(&TaskBUsingCOMSTA));
308 ```
309
310 ## Annotating Tasks with TaskTraits
311
312 [`TaskTraits`](https://cs.chromium.org/chromium/src/base/task_scheduler/task_tra its.h)
313 encapsulate information about a task that helps the task scheduler make better
314 scheduling decisions.
315
316 All `PostTask*()` functions in
317 [`base/task_scheduler/post_task.h`](https://cs.chromium.org/chromium/src/base/ta sk_scheduler/post_task.h)
318 have an overload that takes `TaskTraits` as argument and one that doesn’t. The
319 overload that doesn’t take `TaskTraits` as argument is appropriate for tasks
320 that:
321 - Don’t block (ref. MayBlock and WithBaseSyncPrimitives).
322 - Prefer inheriting the current priority to specifying their own.
323 - Can either block shutdown or be skipped on shutdown (task scheduler is free to choose a fitting default).
324 Tasks that don’t match this description must be posted with explicit TaskTraits.
325
326 [`base/task_scheduler/task_traits.h`](https://cs.chromium.org/chromium/src/base/ task_scheduler/task_traits.h)
327 provides exhaustive documentation of available traits. Below are some examples
328 of how to specify `TaskTraits`.
329
330 ```cpp
331 // This task has no explicit TaskTraits. It cannot block. Its priority
332 // is inherited from the calling context (e.g. if it is posted from
333 // a BACKGROUND task, it will have a BACKGROUND priority). It will either
334 // block shutdown or be skipped on shutdown.
335 base::PostTask(FROM_HERE, base::BindOnce(...));
336
337 // This task has the highest priority. The task scheduler will try to
338 // run it before USER_VISIBLE and BACKGROUND tasks.
339 base::PostTaskWithTraits(
340 FROM_HERE, {base::TaskPriority::USER_BLOCKING},
341 base::BindOnce(...));
342
343 // This task has the lowest priority and is allowed to block (e.g. it
344 // can read a file from disk).
345 base::PostTaskWithTraits(
346 FROM_HERE, {base::TaskPriority::BACKGROUND, base::MayBlock()},
347 base::BindOnce(...));
348
349 // This task blocks shutdown. The process won't exit before its
350 // execution is complete.
351 base::PostTaskWithTraits(
352 FROM_HERE, {base::TaskShutdownBehavior::BLOCK_SHUTDOWN},
353 base::BindOnce(...));
354 ```
355
356 ## Keeping the Browser Responsive
357
358 Do not perform expensive work on the main thread, the IO thread or any sequence
359 that is expected to run tasks with a low latency. Instead, perform expensive
360 work asynchronously using `base::PostTaskAndReply*()` or
361 `SequencedTaskRunner::PostTaskAndReply()`.
362
363 Example: Running the code below on the main thread will prevent the browser from
364 responding to user input for a long time.
365
366 ```cpp
367 // GetHistoryItemsFromDisk() may block for a long time.
368 // AddHistoryItemsToOmniboxDropDown() updates the UI and therefore must
369 // be called on the main thread.
370 AddHistoryItemsToOmniboxDropdown(GetHistoryItemsFromDisk("keyword"));
371 ```
372
373 The code below solves the problem by scheduling a call to
374 `GetHistoryItemsFromDisk()` in a thread pool followed by a call to
375 `AddHistoryItemsToOmniboxDropdown()` on the origin sequence (the main thread in
376 this case). The return value of the first call is automatically provided as
377 argument to the second call.
378
379 ```cpp
380 base::PostTaskWithTraitsAndReplyWithResult(
381 FROM_HERE, {base::MayBlock()},
382 base::BindOnce(&GetHistoryItemsFromDisk, "keyword"),
383 base::BindOnce(&AddHistoryItemsToOmniboxDropdown));
384 ```
385
386 ## Posting a Task with a Delay
387
388 ### Posting a One-Off Task with a Delay
389
390 To post a task that must run once after a delay expires, use
391 `base::PostDelayedTask*()` or `TaskRunner::PostDelayedTask()`.
392
393 ```cpp
394 base::PostDelayedTaskWithTraits(
395 FROM_HERE, {base::TaskPriority::BACKGROUND}, base::BindOnce(&Task),
396 base::TimeDelta::FromHours(1));
397
398 scoped_refptr<base::SequencedTaskRunner> task_runner =
399 base::CreateSequencedTaskRunnerWithTraits({base::TaskPriority::BACKGROUND});
400 task_runner->PostDelayedTask(
401 FROM_HERE, base::BindOnce(&Task), base::TimeDelta::FromHours(1));
402 ```
403
404 *** note
405 **NOTE:** A task that has a 1-hour delay probably doesn’t have to run right away
406 when its delay expires. Specify `base::TaskPriority::BACKGROUND` to prevent it
407 from slowing down the browser when its delay expires.
408 ***
409
410 ### Posting a Repeating Task with a Delay
411 To post a task that must run at regular intervals,
412 use [`base::RepeatingTimer`](https://cs.chromium.org/chromium/src/base/timer/tim er.h).
413
414 ```cpp
415 class A {
416 public:
417 ~A() {
418 // The timer is stopped automatically when it is deleted.
419 }
420 void StartDoingStuff() {
421 timer_.Start(FROM_HERE, TimeDelta::FromSeconds(1),
422 this, &MyClass::DoStuff);
423 }
424 void StopDoingStuff() {
425 timer_.Stop();
426 }
427 private:
428 void DoStuff() {
429 // This method is called every second on the sequence that invoked
430 // StartDoingStuff().
431 }
432 base::RepeatingTimer timer_;
433 };
434 ```
435
436 ## Cancelling a Task
437
438 ### Using base::WeakPtr
439
440 [`base::WeakPtr`](https://cs.chromium.org/chromium/src/base/memory/weak_ptr.h)
441 can be used to ensure that any callback bound to an object is canceled when that
442 object is destroyed.
443
444 ```cpp
445 int Compute() { … }
446
447 class A {
448 public:
449 A() : weak_ptr_factory_(this) {}
450
451 void ComputeAndStore() {
452 // Schedule a call to Compute() in a thread pool followed by
453 // a call to A::Store() on the current sequence. The call to
454 // A::Store() is canceled when |weak_ptr_factory_| is destroyed.
455 // (guarantees that |this| will not be used-after-free).
456 base::PostTaskAndReplyWithResult(
457 FROM_HERE, base::BindOnce(&Compute),
458 base::BindOnce(&A::Store, weak_ptr_factory_.GetWeakPtr()));
459 }
460
461 private:
462 void Store(int value) { value_ = value; }
463
464 int value_;
465 base::WeakPtrFactory<A> weak_ptr_factory_;
466 };
467 ```
468
469 Note: `WeakPtr` is not thread-safe: `GetWeakPtr()`, `~WeakPtrFactory()`, and
470 `Compute()` (bound to a `WeakPtr`) must all run on the same sequence.
471
472 ### Using base::CancelableTaskTracker
473
474 [`base::CancelableTaskTracker`](https://cs.chromium.org/chromium/src/base/task/c ancelable_task_tracker.h)
475 allows cancellation to happen on a different sequence than the one on which
476 tasks run. Keep in mind that `CancelableTaskTracker` cannot cancel tasks that
477 have already started to run.
478
479 ```cpp
480 auto task_runner = base::CreateTaskRunnerWithTraits(base::TaskTraits());
481 base::CancelableTaskTracker cancelable_task_tracker;
482 cancelable_task_tracker.PostTask(task_runner.get(), FROM_HERE,
483 base::Bind(&base::DoNothing));
484 // Cancels Task(), only if it hasn't already started running.
485 cancelable_task_tracker.TryCancelAll();
486 ```
487
488 ## Testing
489
490 To test code that uses `base::ThreadTaskRunnerHandle`,
491 `base::SequencedTaskRunnerHandle` or a function in
492 [`base/task_scheduler/post_task.h`](https://cs.chromium.org/chromium/src/base/ta sk_scheduler/post_task.h), instantiate a
493 [`base::test::ScopedTaskEnvironment`](https://cs.chromium.org/chromium/src/base/ test/scoped_task_environment.h)
494 for the scope of the test.
495
496 ```cpp
497 class MyTest : public testing::Test {
498 public:
499 // ...
500 protected:
501 base::test::ScopedTaskEnvironment scoped_task_environment_;
502 };
503
504 TEST(MyTest, MyTest) {
505 base::ThreadTaskRunnerHandle::Get()->PostTask(FROM_HERE, base::BindOnce(&A));
506 base::SequencedTaskRunnerHandle::Get()->PostTask(FROM_HERE,
507 base::BindOnce(&B));
508 base::ThreadTaskRunnerHandle::Get()->PostDelayedTask(
509 FROM_HERE, base::BindOnce(&C), base::TimeDelta::Max());
510
511 // This runs the (Thread|Sequenced)TaskRunnerHandle queue until it is empty.
512 // Delayed tasks are not added to the queue until they are ripe for execution.
513 base::RunLoop().RunUntilIdle();
514 // A and B have been executed. C is not ripe for execution yet.
515
516 base::RunLoop run_loop;
517 base::ThreadTaskRunnerHandle::Get()->PostTask(FROM_HERE, base::BindOnce(&D));
518 base::ThreadTaskRunnerHandle::Get()->PostTask(FROM_HERE, run_loop.QuitClosure( ));
519 base::ThreadTaskRunnerHandle::Get()->PostTask(FROM_HERE, base::BindOnce(&E));
520
521 // This runs the (Thread|Sequenced)TaskRunnerHandle queue until QuitClosure is
522 // invoked.
523 run_loop.Run();
524 // D and run_loop.QuitClosure() have been executed. E is still in the queue.
525
526 // Tasks posted to task scheduler run asynchronously as they are posted.
527 base::PostTaskWithTraits(FROM_HERE, base::TaskTraits(), base::BindOnce(&F));
528 auto task_runner =
529 base::CreateSequencedTaskRunnerWithTraits(base::TaskTraits());
530 task_runner->PostTask(FROM_HERE, base::BindOnce(&G));
531
532 // To block until all tasks posted to task scheduler are done running:
533 base::TaskScheduler::GetInstance()->FlushForTesting();
534 // F and G have been executed.
535
536 base::PostTaskWithTraitsAndReplyWithResult(
537 FROM_HERE, base::TaskTrait(),
538 base::BindOnce(&H), base::BindOnce(&I));
539
540 // This runs the (Thread|Sequenced)TaskRunnerHandle queue until both the
541 // (Thread|Sequenced)TaskRunnerHandle queue and the TaskSchedule queue are
542 // empty:
543 scoped_task_environment_.RunUntilIdle();
544 // E, H, I have been executed.
545 }
546 ```
547
548 ## Legacy Post Task APIs
549
550 The Chrome browser process has a few legacy named threads (aka
551 “BrowserThreads”). Each of these threads runs a specific type of task (e.g. the
552 `FILE` thread handles low priority file operations, the `FILE_USER_BLOCKING`
553 thread handles high priority file operations, the `CACHE` thread handles cache
554 operations…). Usage of these named threads is now discouraged. New code should
555 post tasks to task scheduler via
556 [`base/task_scheduler/post_task.h`](https://cs.chromium.org/chromium/src/base/ta sk_scheduler/post_task.h)
557 instead.
558
559 If for some reason you absolutely need to post a task to a legacy named thread
560 (e.g. because it needs mutual exclusion with a task running on one of these
561 threads), this is how you do it:
562
563 ```cpp
564 content::BrowserThread::GetTaskRunnerForThread(content::BrowserThread::[IDENTIFI ER])
565 ->PostTask(FROM_HERE, base::BindOnce(&Task));
566 ```
567
568 Where `IDENTIFIER` is one of: `DB`, `FILE`, `FILE_USER_BLOCKING`, `PROCESS_LAUNC HER`, `CACHE`.
569
570 The Chrome browser process has a “blocking pool” API:
571
572 ```cpp
573 content::BrowserThread::PostBlockingPoolSequencedTask
574 content::BrowserThread::GetBlockingPool
575 ```
576
577 All tasks posted through this API are redirected to
578 [`base/task_scheduler/post_task.h`](https://cs.chromium.org/chromium/src/base/ta sk_scheduler/post_task.h).
579 Therefore, there is no reason to add calls to this API.
580
581 ## Using TaskScheduler in a New Process
582
583 TaskScheduler needs to be initialized in a process before the functions in
584 [`base/task_scheduler/post_task.h`](https://cs.chromium.org/chromium/src/base/ta sk_scheduler/post_task.h)
585 can be used. Initialization of TaskScheduler in the Chrome browser process and
586 child processes (renderer, GPU, utility) has already been taken care of. To use
587 TaskScheduler in another process, initialize TaskScheduler early in the main
588 function:
589
590 ```cpp
591 // This initializes and starts TaskScheduler with default params.
592 base::TaskScheduler::CreateAndStartWithDefaultParams(“process_name”);
593 // The base/task_scheduler/post_task.h API can now be used. Tasks will be
594 // scheduled as they are posted.
595
596 // This initializes TaskScheduler.
597 base::TaskScheduler::Create(“process_name”);
598 // The base/task_scheduler/post_task.h API can now be used. No threads
599 // will be created and no tasks will be scheduled until after Start() is called.
600 base::TaskScheduler::GetInstance()->Start(params);
601 // TaskScheduler can now create threads and schedule tasks.
602 ```
603
604 And shutdown TaskScheduler late in the main function:
605
606 ```cpp
607 base::TaskScheduler::GetInstance()->Shutdown();
608 // Tasks posted with TaskShutdownBehavior::BLOCK_SHUTDOWN and
609 // tasks posted with TaskShutdownBehavior::SKIP_ON_SHUTDOWN that
610 // have started to run before the Shutdown() call have now completed their
611 // execution. Tasks posted with
612 // TaskShutdownBehavior::CONTINUE_ON_SHUTDOWN may still be
613 // running.
614 ```
OLDNEW
« no previous file with comments | « docs/README.md ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698