Google OR-Tools v9.15
a fast and portable software suite for combinatorial optimization
Loading...
Searching...
No Matches
threadpool.h
Go to the documentation of this file.
1// Copyright 2010-2025 Google LLC
2// Licensed under the Apache License, Version 2.0 (the "License");
3// you may not use this file except in compliance with the License.
4// You may obtain a copy of the License at
5//
6// http://www.apache.org/licenses/LICENSE-2.0
7//
8// Unless required by applicable law or agreed to in writing, software
9// distributed under the License is distributed on an "AS IS" BASIS,
10// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
11// See the License for the specific language governing permissions and
12// limitations under the License.
13
14#ifndef ORTOOLS_BASE_THREADPOOL_H_
15#define ORTOOLS_BASE_THREADPOOL_H_
16
17#include <cstddef>
18#include <deque>
19#include <optional>
20#include <thread> // NOLINT
21#include <vector>
22
23#include "absl/base/nullability.h"
24#include "absl/base/thread_annotations.h"
25#include "absl/functional/any_invocable.h"
26#include "absl/strings/string_view.h"
27#include "absl/synchronization/mutex.h"
28
29namespace operations_research {
30
32 public:
33 explicit ThreadPool(int num_threads);
34 ThreadPool(absl::string_view prefix, int num_threads);
36
37 void Schedule(absl::AnyInvocable<void() &&> callback);
38
39 private:
40 // Waiter for a single thread.
41 struct Waiter {
42 absl::CondVar cv; // signalled when there is work to do
43 };
44
45 // Spawn a single new worker thread.
46 //
47 // REQUIRES: threads_.size() < max_threads_
48 void SpawnThread() ABSL_EXCLUSIVE_LOCKS_REQUIRED(mutex_);
49
50 void RunWorker();
51
52 // Removes the oldest element from the queue and returns it. Causes the
53 // current thread to wait for producers if the queue is empty. Returns
54 // an empty `std::optional` if the thread pool is shutting down.
55 std::optional<absl::AnyInvocable<void() &&>> DequeueWork()
56 ABSL_LOCKS_EXCLUDED(mutex_);
57
58 // Signals a waiter if there is one, or spawns a thread to try to add a new
59 // waiter.
60 //
61 // REQUIRES: !queue_.empty()
62 void SignalWaiter() ABSL_EXCLUSIVE_LOCKS_REQUIRED(mutex_);
63
64 mutable absl::Mutex mutex_;
65 absl::CondVar wait_nonfull_ ABSL_GUARDED_BY(mutex_);
66 std::vector<Waiter* absl_nonnull> waiters_ ABSL_GUARDED_BY(mutex_);
67 const size_t max_threads_;
68 std::deque<absl::AnyInvocable<void() &&>> queue_;
69 bool stopping_ ABSL_GUARDED_BY(mutex_) = false;
70 size_t running_threads_ ABSL_GUARDED_BY(mutex_) = 0;
71 std::vector<std::thread> threads_ ABSL_GUARDED_BY(mutex_);
72};
73
74} // namespace operations_research
75#endif // ORTOOLS_BASE_THREADPOOL_H_
void Schedule(absl::AnyInvocable< void() && > callback)
OR-Tools root namespace.