1
0
mirror of https://github.com/bshoshany/thread-pool.git synced 2026-07-29 23:12:59 +04:00

2 Commits

Author SHA1 Message Date
Barak Shoshany 097aa718f2 Updated to v4.1.0 2024-03-22 22:06:04 -04:00
Barak Shoshany 6790920f61 Updated to v4.0.1 2023-12-28 12:57:15 -05:00
10 changed files with 272 additions and 179 deletions
+34 -35
View File
@@ -1,4 +1,3 @@
---
AccessModifierOffset: -4 AccessModifierOffset: -4
AlignAfterOpenBracket: DontAlign AlignAfterOpenBracket: DontAlign
AlignArrayOfStructures: None AlignArrayOfStructures: None
@@ -7,12 +6,12 @@ AlignConsecutiveBitFields: None
AlignConsecutiveDeclarations: None AlignConsecutiveDeclarations: None
AlignConsecutiveMacros: None AlignConsecutiveMacros: None
AlignConsecutiveShortCaseStatements: AlignConsecutiveShortCaseStatements:
Enabled: false Enabled: false
AlignEscapedNewlines: Left AlignEscapedNewlines: Left
AlignOperands: DontAlign AlignOperands: DontAlign
AlignTrailingComments: AlignTrailingComments:
Kind: Always Kind: Always
OverEmptyLines: 1 OverEmptyLines: 2
AllowAllArgumentsOnNextLine: false AllowAllArgumentsOnNextLine: false
AllowAllParametersOfDeclarationOnNextLine: false AllowAllParametersOfDeclarationOnNextLine: false
AllowBreakBeforeNoexceptSpecifier: Never AllowBreakBeforeNoexceptSpecifier: Never
@@ -26,29 +25,29 @@ AllowShortLambdasOnASingleLine: Empty
AllowShortLoopsOnASingleLine: false AllowShortLoopsOnASingleLine: false
AlwaysBreakAfterReturnType: None AlwaysBreakAfterReturnType: None
AlwaysBreakBeforeMultilineStrings: false AlwaysBreakBeforeMultilineStrings: false
AlwaysBreakTemplateDeclarations: "Yes" AlwaysBreakTemplateDeclarations: Yes
AttributeMacros: [] AttributeMacros: []
BinPackArguments: true BinPackArguments: true
BinPackParameters: true BinPackParameters: true
BitFieldColonSpacing: Both BitFieldColonSpacing: Both
BraceWrapping: BraceWrapping:
AfterCaseLabel: true AfterCaseLabel: true
AfterClass: true AfterClass: true
AfterControlStatement: Always AfterControlStatement: Always
AfterEnum: true AfterEnum: true
AfterExternBlock: true AfterExternBlock: true
AfterFunction: true AfterFunction: true
AfterNamespace: false AfterNamespace: false
AfterStruct: true AfterStruct: true
AfterUnion: true AfterUnion: true
BeforeCatch: true BeforeCatch: true
BeforeElse: true BeforeElse: true
BeforeLambdaBody: true BeforeLambdaBody: true
BeforeWhile: false BeforeWhile: false
IndentBraces: false IndentBraces: false
SplitEmptyFunction: true SplitEmptyFunction: true
SplitEmptyNamespace: true SplitEmptyNamespace: true
SplitEmptyRecord: true SplitEmptyRecord: true
BracedInitializerIndentWidth: 4 BracedInitializerIndentWidth: 4
BreakAdjacentStringLiterals: false BreakAdjacentStringLiterals: false
BreakAfterAttributes: Never BreakAfterAttributes: Never
@@ -75,13 +74,13 @@ EmptyLineBeforeAccessModifier: LogicalBlock
ExperimentalAutoDetectBinPacking: false ExperimentalAutoDetectBinPacking: false
FixNamespaceComments: true FixNamespaceComments: true
IncludeBlocks: Preserve IncludeBlocks: Preserve
IncludeIsMainSourceRegex: "" IncludeIsMainSourceRegex: ''
IndentAccessModifiers: false IndentAccessModifiers: false
IndentCaseBlocks: false IndentCaseBlocks: false
IndentCaseLabels: false IndentCaseLabels: false
IndentExternBlock: AfterExternBlock IndentExternBlock: AfterExternBlock
IndentGotoLabels: true IndentGotoLabels: true
IndentPPDirectives: None IndentPPDirectives: BeforeHash
IndentRequires: false IndentRequires: false
IndentWidth: 4 IndentWidth: 4
IndentWrappedFunctionNames: false IndentWrappedFunctionNames: false
@@ -90,8 +89,8 @@ JavaScriptWrapImports: true
KeepEmptyLinesAtTheStartOfBlocks: true KeepEmptyLinesAtTheStartOfBlocks: true
LambdaBodyIndentation: Signature LambdaBodyIndentation: Signature
Language: Cpp Language: Cpp
MacroBlockBegin: "" MacroBlockBegin: ''
MacroBlockEnd: "" MacroBlockEnd: ''
MaxEmptyLinesToKeep: 1 MaxEmptyLinesToKeep: 1
NamespaceIndentation: Inner NamespaceIndentation: Inner
ObjCBinPackProtocolList: Auto ObjCBinPackProtocolList: Auto
@@ -132,13 +131,13 @@ SpaceBeforeCtorInitializerColon: true
SpaceBeforeInheritanceColon: true SpaceBeforeInheritanceColon: true
SpaceBeforeParens: ControlStatements SpaceBeforeParens: ControlStatements
SpaceBeforeParensOptions: SpaceBeforeParensOptions:
AfterControlStatements: true AfterControlStatements: true
AfterForeachMacros: true AfterForeachMacros: true
AfterFunctionDeclarationName: false AfterFunctionDeclarationName: false
AfterFunctionDefinitionName: false AfterFunctionDefinitionName: false
AfterIfMacros: true AfterIfMacros: true
AfterOverloadedOperator: false AfterOverloadedOperator: false
BeforeNonEmptyParentheses: false BeforeNonEmptyParentheses: false
SpaceBeforeRangeBasedForLoopColon: true SpaceBeforeRangeBasedForLoopColon: true
SpaceBeforeSquareBrackets: false SpaceBeforeSquareBrackets: false
SpaceInEmptyBlock: false SpaceInEmptyBlock: false
@@ -149,8 +148,8 @@ SpacesInCStyleCastParentheses: false
SpacesInConditionalStatement: false SpacesInConditionalStatement: false
SpacesInContainerLiterals: true SpacesInContainerLiterals: true
SpacesInLineCommentPrefix: SpacesInLineCommentPrefix:
Maximum: 1 Maximum: 1
Minimum: 1 Minimum: 1
SpacesInParentheses: false SpacesInParentheses: false
SpacesInSquareBrackets: false SpacesInSquareBrackets: false
Standard: c++17 Standard: c++17
+21
View File
@@ -6,6 +6,8 @@ Website: <https://baraksh.com/>\
GitHub: <https://github.com/bshoshany> GitHub: <https://github.com/bshoshany>
* [Version history](#version-history) * [Version history](#version-history)
* [v4.1.0 (2024-03-22)](#v410-2024-03-22)
* [v4.0.1 (2023-12-28)](#v401-2023-12-28)
* [v4.0.0 (2023-12-27)](#v400-2023-12-27) * [v4.0.0 (2023-12-27)](#v400-2023-12-27)
* [v3.5.0 (2023-05-25)](#v350-2023-05-25) * [v3.5.0 (2023-05-25)](#v350-2023-05-25)
* [v3.4.0 (2023-05-12)](#v340-2023-05-12) * [v3.4.0 (2023-05-12)](#v340-2023-05-12)
@@ -27,6 +29,25 @@ GitHub: <https://github.com/bshoshany>
## Version history ## Version history
### v4.1.0 (2024-03-22)
* This library is now published in [SoftwareX](https://www.sciencedirect.com/journal/softwarex)! If you use it in published research, please cite it as follows: Barak Shoshany, *"A C++17 Thread Pool for High-Performance Scientific Computing"*, [doi:10.1016/j.softx.2024.101687](https://doi.org/10.1016/j.softx.2024.101687), [SoftwareX 26 (2024) 101687](https://www.sciencedirect.com/science/article/pii/S235271102400058X), [arXiv:2105.00613](https://arxiv.org/abs/2105.00613)
* Updated the source files, as well as `README.md`, `CITATION.bib`, and `CITATION.cff` with the new citation.
* A new macro, `BS_THREAD_POOL_DISABLE_EXCEPTION_HANDLING`, allows the user to disable exception handling in `submit_task()` if it is not needed, or if exceptions are explicitly disabled in the codebase. See [#139](https://github.com/bshoshany/thread-pool/issues/139).
* Note that this macro can be defined independently of `BS_THREAD_POOL_ENABLE_WAIT_DEADLOCK_CHECK`. Disabling exception handling removes the `try`-`catch` block from `submit_task()`, while enabling wait deadlock checks adds a `throw` expression to `wait()`, `wait_for()`, and `wait_until()`.
* If the feature-test macro `__cpp_exceptions` is undefined, `BS_THREAD_POOL_DISABLE_EXCEPTION_HANDLING` is automatically defined, and `BS_THREAD_POOL_ENABLE_WAIT_DEADLOCK_CHECK` is automatically undefined.
* Replaced `#pragma once` with old-school include guards using the macros `BS_THREAD_POOL_HPP` and `BS_THREAD_POOL_UTILS_HPP`. There are two main reasons for this:
1. Even though `#pragma once` is supported by the vast majority of modern compilers, it is still a non-standard feature, so using it technically made the library not standards compliant.
2. Include guards make it possible to include the library twice in the same project (for example, once with priority enabled and once without) by undefining the include guard and putting the second include in its own namespace.
* Included a description of the destructor behavior for the `BS::thread_pool` class in `README.md`, in the library reference section. See [#143](https://github.com/bshoshany/thread-pool/issues/143).
* Removed unnecessary locking in `reset()` if pausing is not enabled.
### v4.0.1 (2023-12-28)
* Fixed linkage issue caused by the global variables `BS::this_thread::get_index` and `BS::this_thread::get_pool` not being defined as `inline`. See [#134](https://github.com/bshoshany/thread-pool/issues/134) and [137](https://github.com/bshoshany/thread-pool/issues/137).
* Fixed redundant cast in the `BS::thread_pool::blocks` class, and added `-Wuseless-cast` to the GCC warning flags in `BS_thread_pool_test.ps1` to catch similar issues in the future. See [#133](https://github.com/bshoshany/thread-pool/pull/133).
* Each of the three files `BS_thread_pool_test.cpp`, `BS_thread_pool.hpp`, and `BS_thread_pool_utils.hpp` now contains three macros indicating the major, minor, and patch version of the file. In addition, `BS_thread_pool_test.cpp` now checks whether the versions of all three files match, and aborts compilation if they do not.
### v4.0.0 (2023-12-27) ### v4.0.0 (2023-12-27)
* A major new release with numerous changes, additions, fixes, and improvements. Many frequently requested features have been added, and performance has been optimized. Please note that code written using previous releases will need to be modified to work with the new release. The changes needed to migrate to the new API are explicitly indicated below for your convenience. * A major new release with numerous changes, additions, fixes, and improvements. Many frequently requested features have been added, and performance has been optimized. Please note that code written using previous releases will need to be modified to work with the new release. The changes needed to migrate to the new API are explicitly indicated below for your convenience.
+7 -8
View File
@@ -1,13 +1,12 @@
@article{Shoshany2021_ThreadPool, @article{Shoshany2024_ThreadPool,
archiveprefix = {arXiv}, archiveprefix = {arXiv},
author = {Barak Shoshany}, author = {Barak Shoshany},
doi = {10.5281/zenodo.4742687}, doi = {10.1016/j.softx.2024.101687},
eid = {arXiv:2105.00613},
eprint = {2105.00613}, eprint = {2105.00613},
journal = {arXiv e-prints}, journal = {SoftwareX},
keywords = {Computer Science - Distributed, Parallel, and Cluster Computing, D.1.3, D.1.5}, pages = {101687},
month = {May},
primaryclass = {cs.DC},
title = {{A C++17 Thread Pool for High-Performance Scientific Computing}}, title = {{A C++17 Thread Pool for High-Performance Scientific Computing}},
year = {2021} url = {https://www.sciencedirect.com/science/article/pii/S235271102400058X},
volume = {26},
year = {2024}
} }
+19 -23
View File
@@ -1,26 +1,22 @@
---
authors:
-
family-names: Shoshany
given-names: Barak
orcid: https://orcid.org/0000-0003-2222-127X
cff-version: 1.2.0 cff-version: 1.2.0
date-released: "2021-05-03"
doi: 10.5281/zenodo.4742687
license: MIT
message: If you use this library in published research, please cite it as follows. message: If you use this library in published research, please cite it as follows.
preferred-citation: authors:
authors: - given-names: Barak
- family-names: Shoshany
family-names: Shoshany orcid: https://orcid.org/0000-0003-2222-127X
given-names: Barak email: bshoshany@brocku.ca
orcid: https://orcid.org/0000-0003-2222-127X
doi: 10.5281/zenodo.4742687
journal: arXiv
month: 5
title: A C++17 Thread Pool for High-Performance Scientific Computing
type: article
url: https://arxiv.org/abs/2105.00613
year: 2021
repository-code: https://github.com/bshoshany/thread-pool
title: A C++17 Thread Pool for High-Performance Scientific Computing title: A C++17 Thread Pool for High-Performance Scientific Computing
doi: 10.1016/j.softx.2024.101687
url: https://github.com/bshoshany/thread-pool
preferred-citation:
type: article
authors:
- given-names: Barak
family-names: Shoshany
title: A C++17 Thread Pool for High-Performance Scientific Computing
journal: SoftwareX
volume: 26
year: 2024
start: 101687
doi: 10.1016/j.softx.2024.101687
url: https://www.sciencedirect.com/science/article/pii/S235271102400058X
+1 -1
View File
@@ -1,6 +1,6 @@
MIT License MIT License
Copyright (c) 2023 Barak Shoshany Copyright (c) 2024 Barak Shoshany
Permission is hereby granted, free of charge, to any person obtaining a copy Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal of this software and associated documentation files (the "Software"), to deal
+60 -40
View File
@@ -1,16 +1,15 @@
[![Static Badge](https://img.shields.io/badge/DOI-10.5281%2Fzenodo.4742687-b31b1b) [![Author: Barak Shoshany](https://img.shields.io/badge/author-Barak_Shoshany-009933)](https://baraksh.com/)
](https://doi.org/10.5281/zenodo.4742687) [![DOI: 10.1016/j.softx.2024.101687](https://img.shields.io/badge/DOI-10.1016%2Fj.softx.2024.101687-b31b1b)](https://doi.org/10.1016/j.softx.2024.101687)
[![arXiv:2105.00613](https://img.shields.io/badge/arXiv-2105.00613-b31b1b) [![arXiv:2105.00613](https://img.shields.io/badge/arXiv-2105.00613-b31b1b)](https://arxiv.org/abs/2105.00613)
](https://arxiv.org/abs/2105.00613)
[![License: MIT](https://img.shields.io/github/license/bshoshany/thread-pool)](https://github.com/bshoshany/thread-pool/blob/master/LICENSE.txt) [![License: MIT](https://img.shields.io/github/license/bshoshany/thread-pool)](https://github.com/bshoshany/thread-pool/blob/master/LICENSE.txt)
[![Language: C++17](https://img.shields.io/badge/Language-C%2B%2B17-yellow)](https://cppreference.com) [![Language: C++17](https://img.shields.io/badge/Language-C%2B%2B17-yellow)](https://cppreference.com/)
[![GitHub release](https://img.shields.io/github/v/release/bshoshany/thread-pool)](https://github.com/bshoshany/thread-pool/releases) [![GitHub stars](https://img.shields.io/github/stars/bshoshany/thread-pool?style=flat&color=009999)](https://github.com/bshoshany/thread-pool/stargazers)
[![Vcpkg Version](https://img.shields.io/vcpkg/v/bshoshany-thread-pool)](https://vcpkg.io/) [![GitHub forks](https://img.shields.io/github/forks/bshoshany/thread-pool?style=flat&color=009999)](https://github.com/bshoshany/thread-pool/forks)
[![Conan Version](https://img.shields.io/conan/v/bshoshany-thread-pool)](https://conan.io/center/recipes/bshoshany-thread-pool) [![GitHub release](https://img.shields.io/github/v/release/bshoshany/thread-pool?color=660099)](https://github.com/bshoshany/thread-pool/releases)
[![GitHub Repo stars](https://img.shields.io/github/stars/bshoshany/thread-pool?color=009999)](https://github.com/bshoshany/thread-pool/stargazers) [![Vcpkg version](https://img.shields.io/vcpkg/v/bshoshany-thread-pool?color=6600ff)](https://vcpkg.io/)
[![GitHub forks](https://img.shields.io/github/forks/bshoshany/thread-pool?color=009999)](https://github.com/bshoshany/thread-pool/forks) [![Meson WrapDB](https://img.shields.io/badge/dynamic/json?url=https%3A%2F%2Fraw.githubusercontent.com%2Fmesonbuild%2Fwrapdb%2Fmaster%2Freleases.json&query=%24%5B%22bshoshany-thread-pool%22%5D.versions%5B0%5D&label=wrapdb&color=6600ff)](https://mesonbuild.com/Wrapdb-projects.html)
[![Conan version](https://img.shields.io/conan/v/bshoshany-thread-pool?color=6600ff)](https://conan.io/center/recipes/bshoshany-thread-pool)
[![Open in Visual Studio Code](https://img.shields.io/badge/Open_in_Visual_Studio_Code-007acc)](https://vscode.dev/github/bshoshany/thread-pool) [![Open in Visual Studio Code](https://img.shields.io/badge/Open_in_Visual_Studio_Code-007acc)](https://vscode.dev/github/bshoshany/thread-pool)
[![Barak Shoshany's Website](https://img.shields.io/badge/Barak_Shoshany's_Website-009933)](https://baraksh.com/)
# `BS::thread_pool`: a fast, lightweight, and easy-to-use C++17 thread pool library # `BS::thread_pool`: a fast, lightweight, and easy-to-use C++17 thread pool library
@@ -19,7 +18,7 @@ Email: <baraksh@gmail.com>\
Website: <https://baraksh.com/>\ Website: <https://baraksh.com/>\
GitHub: <https://github.com/bshoshany> GitHub: <https://github.com/bshoshany>
This is the complete documentation for v4.0.0 of the library, released on 2023-12-27. This is the complete documentation for v4.1.0 of the library, released on 2024-03-22.
* [Introduction](#introduction) * [Introduction](#introduction)
* [Motivation](#motivation) * [Motivation](#motivation)
@@ -220,19 +219,25 @@ It is generally unnecessary to change the number of threads in the pool after it
### Finding the version of the library ### Finding the version of the library
If desired, the version of this library may be read during compilation time from the macro `BS_THREAD_POOL_VERSION`. The value will be a string containing the version number and release date. For example: If desired, the version of this library may be read during compilation time from the following three macros:
```cpp * `BS_THREAD_POOL_VERSION_MAJOR` - indicates the major version.
std::cout << "Thread pool library version is " << BS_THREAD_POOL_VERSION << ".\n"; * `BS_THREAD_POOL_VERSION_MINOR` - indicates the minor version.
* `BS_THREAD_POOL_VERSION_PATCH` - indicates the patch version.
```cpp
std::cout << "Thread pool library version is " << BS_THREAD_POOL_VERSION_MAJOR << '.' << BS_THREAD_POOL_VERSION_MINOR << '.' << BS_THREAD_POOL_VERSION_PATCH << ".\n";
``` ```
Sample output: Sample output:
```none ```none
Thread pool library version is v4.0.0 (2023-12-27). Thread pool library version is 4.1.0.
``` ```
This can be used, for example, to allow the same code to work with several incompatible versions of the library. This can be used, for example, to allow the same code base to work with several incompatible versions of the library using `#if` directives.
**Note:** This feature is only available starting with v4.0.1. Earlier releases of this library do not define these macros.
## Submitting tasks to the queue ## Submitting tasks to the queue
@@ -948,7 +953,13 @@ Aside from using `BS::multi_future<T>` to track the execution of parallelized lo
## Utility classes ## Utility classes
The optional header file `BS_thread_pool_utils.hpp` contains several useful utility classes. These are not necessary for using the thread pool itself; `BS_thread_pool.hpp` is the only header file required. However, the utility classes can make writing multithreading code more convenient. The version of the utilities header file can be found by checking the macro `BS_THREAD_POOL_UTILS_VERSION`. The optional header file `BS_thread_pool_utils.hpp` contains several useful utility classes. These are not necessary for using the thread pool itself; `BS_thread_pool.hpp` is the only header file required. However, the utility classes can make writing multithreading code more convenient.
As with [the main header file](#finding-the-version-of-the-library), the version of the utilities header file can be found by checking three macros:
* `BS_THREAD_POOL_UTILS_VERSION_MAJOR` - indicates the major version.
* `BS_THREAD_POOL_UTILS_VERSION_MINOR` - indicates the minor version.
* `BS_THREAD_POOL_UTILS_VERSION_PATCH` - indicates the patch version.
### Synchronizing printing to a stream with `BS::synced_stream` ### Synchronizing printing to a stream with `BS::synced_stream`
@@ -1055,7 +1066,7 @@ Note, however, that `BS::synced_stream::endl` should only be used if flushing is
If you are using a thread pool, then your code is most likely performance-critical. Achieving maximum performance requires performing a considerable amount of benchmarking to determine the optimal settings and algorithms. Therefore, it is important to be able to measure the execution time of various computations and operations under different conditions. If you are using a thread pool, then your code is most likely performance-critical. Achieving maximum performance requires performing a considerable amount of benchmarking to determine the optimal settings and algorithms. Therefore, it is important to be able to measure the execution time of various computations and operations under different conditions.
The helper class `BS::timer` provides a simple way to measure execution time. It is very straightforward to use: The utility class `BS::timer` provides a simple way to measure execution time. It is very straightforward to use:
1. Create a new `BS::timer` object. 1. Create a new `BS::timer` object.
2. Immediately before you execute the computation that you want to time, call the `start()` member function. 2. Immediately before you execute the computation that you want to time, call the `start()` member function.
@@ -1271,6 +1282,8 @@ int main()
When using `BS::multi_future` to handle multiple futures at once, exception handling works the same way: if any of the futures may throw exceptions, you may catch these exceptions when calling `get()`, even in the case of `BS::multi_future<void>`. When using `BS::multi_future` to handle multiple futures at once, exception handling works the same way: if any of the futures may throw exceptions, you may catch these exceptions when calling `get()`, even in the case of `BS::multi_future<void>`.
If you do not require exception handling, or if exceptions are explicitly disabled in your codebase, you can define the macro `BS_THREAD_POOL_DISABLE_EXCEPTION_HANDLING` before including `BS_thread_pool.hpp`, which will disable exception handling in `submit_task()`. Note that if the feature-test macro `__cpp_exceptions` is undefined, `BS_THREAD_POOL_DISABLE_EXCEPTION_HANDLING` will be automatically defined.
### Getting information about the threads ### Getting information about the threads
`BS::thread_pool` comes with a variety of methods to obtain information about the threads in the pool: `BS::thread_pool` comes with a variety of methods to obtain information about the threads in the pool:
@@ -1585,6 +1598,8 @@ int main()
This time, `wait()` will detect the deadlock, and will throw an exception, causing the output to be `"Error: Deadlock!"`. This time, `wait()` will detect the deadlock, and will throw an exception, causing the output to be `"Error: Deadlock!"`.
Note that if the feature-test macro `__cpp_exceptions` is undefined, `BS_THREAD_POOL_ENABLE_WAIT_DEADLOCK_CHECK` will be automatically undefined.
### Accessing native thread handles ### Accessing native thread handles
The `BS::thread_pool` member function `get_native_handles()` returns a vector containing the underlying implementation-defined thread handles for each of the pool's threads. These can then be used in an implementation-specific way to manage the threads at the OS level The `BS::thread_pool` member function `get_native_handles()` returns a vector containing the underlying implementation-defined thread handles for each of the pool's threads. These can then be used in an implementation-specific way to manage the threads at the OS level
@@ -1640,11 +1655,11 @@ BS::thread_pool pool(1);
int main() int main()
{ {
pool.detach_task( [] { sync_out.println("This task will execute third."); }, BS::pr::normal); pool.detach_task([] { sync_out.println("This task will execute third."); }, BS::pr::normal);
pool.detach_task( [] { sync_out.println("This task will execute fifth."); }, BS::pr::lowest); pool.detach_task([] { sync_out.println("This task will execute fifth."); }, BS::pr::lowest);
pool.detach_task( [] { sync_out.println("This task will execute second."); }, BS::pr::high); pool.detach_task([] { sync_out.println("This task will execute second."); }, BS::pr::high);
pool.detach_task( [] { sync_out.println("This task will execute first."); }, BS::pr::highest); pool.detach_task([] { sync_out.println("This task will execute first."); }, BS::pr::highest);
pool.detach_task( [] { sync_out.println("This task will execute fourth."); }, BS::pr::low); pool.detach_task([] { sync_out.println("This task will execute fourth."); }, BS::pr::low);
} }
``` ```
@@ -1771,7 +1786,7 @@ If you are using the [Conan](https://conan.io/) C/C++ package manager, you can e
```ini ```ini
[requires] [requires]
bshoshany-thread-pool/4.0.0 bshoshany-thread-pool/4.1.0
``` ```
To update the package to the latest version, simply change the version number. Please refer to [this package's page on ConanCenter](https://conan.io/center/recipes/bshoshany-thread-pool) for more information. To update the package to the latest version, simply change the version number. Please refer to [this package's page on ConanCenter](https://conan.io/center/recipes/bshoshany-thread-pool) for more information.
@@ -1798,12 +1813,12 @@ If you are using [CMake](https://cmake.org/), you can install `BS::thread_pool`
CPMAddPackage( CPMAddPackage(
NAME BS_thread_pool NAME BS_thread_pool
GITHUB_REPOSITORY bshoshany/thread-pool GITHUB_REPOSITORY bshoshany/thread-pool
VERSION 4.0.0) VERSION 4.1.0)
add_library(BS_thread_pool INTERFACE) add_library(BS_thread_pool INTERFACE)
target_include_directories(BS_thread_pool INTERFACE ${BS_thread_pool_SOURCE_DIR}/include) target_include_directories(BS_thread_pool INTERFACE ${BS_thread_pool_SOURCE_DIR}/include)
``` ```
This will automatically download the indicated version of the package from this GitHub repository and include it in your project. This will automatically download the indicated version of the package from the GitHub repository and include it in your project.
It is also possible to use CPM without installing it first, by adding the following lines to `CMakeLists.txt` before `CPMAddPackage`: It is also possible to use CPM without installing it first, by adding the following lines to `CMakeLists.txt` before `CPMAddPackage`:
@@ -1833,7 +1848,7 @@ include(${CPM_DOWNLOAD_LOCATION})
CPMAddPackage( CPMAddPackage(
NAME BS_thread_pool NAME BS_thread_pool
GITHUB_REPOSITORY bshoshany/thread-pool GITHUB_REPOSITORY bshoshany/thread-pool
VERSION 4.0.0) VERSION 4.1.0)
add_library(BS_thread_pool INTERFACE) add_library(BS_thread_pool INTERFACE)
target_include_directories(BS_thread_pool INTERFACE ${BS_thread_pool_SOURCE_DIR}/include) target_include_directories(BS_thread_pool INTERFACE ${BS_thread_pool_SOURCE_DIR}/include)
add_executable(my_project main.cpp) add_executable(my_project main.cpp)
@@ -1892,6 +1907,8 @@ The class `BS::thread_pool` is the main thread pool class. It can be used to cre
* `bool wait_for(std::chrono::duration<R, P>& duration)`: Wait for tasks to be completed, but stop waiting after the specified duration has passed. Returns `true` if all tasks finished running, `false` if the duration expired but some tasks are still running. * `bool wait_for(std::chrono::duration<R, P>& duration)`: Wait for tasks to be completed, but stop waiting after the specified duration has passed. Returns `true` if all tasks finished running, `false` if the duration expired but some tasks are still running.
* `bool wait_until(std::chrono::time_point<C, D>& timeout_time)`: Wait for tasks to be completed, but stop waiting after the specified time point has been reached. Returns `true` if all tasks finished running, `false` if the time point was reached but some tasks are still running. * `bool wait_until(std::chrono::time_point<C, D>& timeout_time)`: Wait for tasks to be completed, but stop waiting after the specified time point has been reached. Returns `true` if all tasks finished running, `false` if the time point was reached but some tasks are still running.
When a `BS::thread_pool` object goes out of scope, the destructor first waits for all tasks to complete, then destroys all threads. Note that if the pool is paused, then any tasks still in the queue will never be executed.
#### Optional features for the `BS::thread_pool` class #### Optional features for the `BS::thread_pool` class
The thread pool has several optional features that must be explicitly enabled using macros. The thread pool has several optional features that must be explicitly enabled using macros.
@@ -1908,6 +1925,10 @@ The thread pool has several optional features that must be explicitly enabled us
* `std::vector<std::thread::native_handle_type> get_native_handles()`: Get a vector containing the underlying implementation-defined thread handles for each of the pool's threads. * `std::vector<std::thread::native_handle_type> get_native_handles()`: Get a vector containing the underlying implementation-defined thread handles for each of the pool's threads.
* **Wait deadlock checks:** Enabled by defining the macro `BS_THREAD_POOL_ENABLE_WAIT_DEADLOCK_CHECK`. * **Wait deadlock checks:** Enabled by defining the macro `BS_THREAD_POOL_ENABLE_WAIT_DEADLOCK_CHECK`.
* When enabled, `wait()`, `wait_for()`, and `wait_until()` will check whether the user tried to call them from within a thread of the same pool, which would result in a deadlock. If so, they will throw the exception `BS::thread_pool::wait_deadlock` instead of waiting. * When enabled, `wait()`, `wait_for()`, and `wait_until()` will check whether the user tried to call them from within a thread of the same pool, which would result in a deadlock. If so, they will throw the exception `BS::thread_pool::wait_deadlock` instead of waiting.
* **Disabling exception handling**: Achieved by defining the macro `BS_THREAD_POOL_DISABLE_EXCEPTION_HANDLING`.
* This can be used to disable exception handling in `submit_task()` if it is not needed, or if exceptions are explicitly disabled in the codebase.
* Note that this macro can be defined independently of `BS_THREAD_POOL_ENABLE_WAIT_DEADLOCK_CHECK`. Disabling exception handling removes the `try`-`catch` block from `submit_task()`, while enabling wait deadlock checks adds a `throw` expression to `wait()`, `wait_for()`, and `wait_until()`.
* If the feature-test macro `__cpp_exceptions` is undefined, `BS_THREAD_POOL_DISABLE_EXCEPTION_HANDLING` is automatically defined, and `BS_THREAD_POOL_ENABLE_WAIT_DEADLOCK_CHECK` is automatically undefined.
#### The `BS::this_thread` namespace #### The `BS::this_thread` namespace
@@ -1981,33 +2002,32 @@ If you found this project useful, please consider [starring it on GitHub](https:
### Copyright and citing ### Copyright and citing
Copyright (c) 2023 [Barak Shoshany](http://baraksh.com). Licensed under the [MIT license](LICENSE.txt). Copyright (c) 2024 [Barak Shoshany](https://baraksh.com). Licensed under the [MIT license](LICENSE.txt).
If you use this C++ thread pool library in software of any kind, please provide a link to [the GitHub repository](https://github.com/bshoshany/thread-pool) in the source code and documentation. If you use this C++ thread pool library in software of any kind, please provide a link to [the GitHub repository](https://github.com/bshoshany/thread-pool) in the source code and documentation.
If you use this library in published research, please cite it as follows: If you use this library in published research, please cite it as follows:
* Barak Shoshany, *"A C++17 Thread Pool for High-Performance Scientific Computing"*, [doi:10.5281/zenodo.4742687](https://doi.org/10.5281/zenodo.4742687), [arXiv:2105.00613](https://arxiv.org/abs/2105.00613) (May 2021) * Barak Shoshany, *"A C++17 Thread Pool for High-Performance Scientific Computing"*, [doi:10.1016/j.softx.2024.101687](https://doi.org/10.1016/j.softx.2024.101687), [SoftwareX 26 (2024) 101687](https://www.sciencedirect.com/science/article/pii/S235271102400058X), [arXiv:2105.00613](https://arxiv.org/abs/2105.00613)
You can use the following BibTeX entry: You can use the following BibTeX entry:
```none ```bibtex
@article{Shoshany2021_ThreadPool, @article{Shoshany2024_ThreadPool,
archiveprefix = {arXiv}, archiveprefix = {arXiv},
author = {Barak Shoshany}, author = {Barak Shoshany},
doi = {10.5281/zenodo.4742687}, doi = {10.1016/j.softx.2024.101687},
eid = {arXiv:2105.00613},
eprint = {2105.00613}, eprint = {2105.00613},
journal = {arXiv e-prints}, journal = {SoftwareX},
keywords = {Computer Science - Distributed, Parallel, and Cluster Computing, D.1.3, D.1.5}, pages = {101687},
month = {May},
primaryclass = {cs.DC},
title = {{A C++17 Thread Pool for High-Performance Scientific Computing}}, title = {{A C++17 Thread Pool for High-Performance Scientific Computing}},
year = {2021} url = {https://www.sciencedirect.com/science/article/pii/S235271102400058X},
volume = {26},
year = {2024}
} }
``` ```
Please note that the [companion paper on arXiv](https://arxiv.org/abs/2105.00613) is updated infrequently. The paper is intended to facilitate discovery of the library by scientists who may find it useful for scientific computing purposes and to allow citing the library in scientific research, but most users should read the `README.md` file on [the GitHub repository](https://github.com/bshoshany/thread-pool) instead, as it is guaranteed to always be up to date. Please note that the papers on [SoftwareX](https://www.sciencedirect.com/science/article/pii/S235271102400058X) and [arXiv](https://arxiv.org/abs/2105.00613) are not up to date with the latest version of the library. These publications are only intended to facilitate discovery of this library by scientists, and to enable citing it in scientific research. Documentation for the latest version is provided only by the `README.md` file in [the GitHub repository](https://github.com/bshoshany/thread-pool).
### Learning more about C++ ### Learning more about C++
+45 -27
View File
@@ -1,29 +1,40 @@
#pragma once #ifndef BS_THREAD_POOL_HPP
#define BS_THREAD_POOL_HPP
/** /**
* @file BS_thread_pool.hpp * @file BS_thread_pool.hpp
* @author Barak Shoshany (baraksh@gmail.com) (http://baraksh.com) * @author Barak Shoshany (baraksh@gmail.com) (https://baraksh.com)
* @version 4.0.0 * @version 4.1.0
* @date 2023-12-27 * @date 2024-03-22
* @copyright Copyright (c) 2023 Barak Shoshany. Licensed under the MIT license. If you found this project useful, please consider starring it on GitHub! If you use this library in software of any kind, please provide a link to the GitHub repository https://github.com/bshoshany/thread-pool in the source code and documentation. If you use this library in published research, please cite it as follows: Barak Shoshany, "A C++17 Thread Pool for High-Performance Scientific Computing", doi:10.5281/zenodo.4742687, arXiv:2105.00613 (May 2021) * @copyright Copyright (c) 2024 Barak Shoshany. Licensed under the MIT license. If you found this project useful, please consider starring it on GitHub! If you use this library in software of any kind, please provide a link to the GitHub repository https://github.com/bshoshany/thread-pool in the source code and documentation. If you use this library in published research, please cite it as follows: Barak Shoshany, "A C++17 Thread Pool for High-Performance Scientific Computing", doi:10.1016/j.softx.2024.101687, SoftwareX 26 (2024) 101687, arXiv:2105.00613
* *
* @brief BS::thread_pool: a fast, lightweight, and easy-to-use C++17 thread pool library. This header file contains the main thread pool class and some additional classes and definitions. No other files are needed in order to use the thread pool itself. * @brief BS::thread_pool: a fast, lightweight, and easy-to-use C++17 thread pool library. This header file contains the main thread pool class and some additional classes and definitions. No other files are needed in order to use the thread pool itself.
*/ */
#ifndef __cpp_exceptions
#define BS_THREAD_POOL_DISABLE_EXCEPTION_HANDLING
#undef BS_THREAD_POOL_ENABLE_WAIT_DEADLOCK_CHECK
#endif
#include <chrono> // std::chrono #include <chrono> // std::chrono
#include <condition_variable> // std::condition_variable #include <condition_variable> // std::condition_variable
#include <cstddef> // std::size_t #include <cstddef> // std::size_t
#include <cstdint> // std::int_least16_t #ifdef BS_THREAD_POOL_ENABLE_PRIORITY
#include <exception> // std::current_exception #include <cstdint> // std::int_least16_t
#endif
#ifndef BS_THREAD_POOL_DISABLE_EXCEPTION_HANDLING
#include <exception> // std::current_exception
#endif
#include <functional> // std::function #include <functional> // std::function
#include <future> // std::future, std::future_status, std::promise #include <future> // std::future, std::future_status, std::promise
#include <memory> // std::make_shared, std::make_unique, std::shared_ptr, std::unique_ptr #include <memory> // std::make_shared, std::make_unique, std::shared_ptr, std::unique_ptr
#include <mutex> // std::mutex, std::scoped_lock, std::unique_lock #include <mutex> // std::mutex, std::scoped_lock, std::unique_lock
#include <optional> // std::nullopt, std::optional #include <optional> // std::nullopt, std::optional
#include <queue> // std::priority_queue, std::queue #include <queue> // std::priority_queue (if priority enabled), std::queue
#include <stdexcept> // std::runtime_error #ifdef BS_THREAD_POOL_ENABLE_WAIT_DEADLOCK_CHECK
#include <stdexcept> // std::runtime_error
#endif
#include <thread> // std::thread #include <thread> // std::thread
#include <type_traits> // std::conditional_t, std::decay_t, std::invoke_result_t, std::is_void_v, std::remove_const_t #include <type_traits> // std::conditional_t, std::decay_t, std::invoke_result_t, std::is_void_v, std::remove_const_t (if priority enabled)
#include <utility> // std::forward, std::move #include <utility> // std::forward, std::move
#include <vector> // std::vector #include <vector> // std::vector
@@ -31,8 +42,10 @@
* @brief A namespace used by Barak Shoshany's projects. * @brief A namespace used by Barak Shoshany's projects.
*/ */
namespace BS { namespace BS {
// A macro containing the version of the thread pool library. // Macros indicating the version of the thread pool library.
#define BS_THREAD_POOL_VERSION "v4.0.0 (2023-12-27)" #define BS_THREAD_POOL_VERSION_MAJOR 4
#define BS_THREAD_POOL_VERSION_MINOR 1
#define BS_THREAD_POOL_VERSION_PATCH 0
class thread_pool; class thread_pool;
@@ -63,12 +76,12 @@ namespace pr {
constexpr priority_t lowest = -32768; constexpr priority_t lowest = -32768;
} // namespace pr } // namespace pr
// Macros used internally to enable or disable the priority arguments in the relevant functions. // Macros used internally to enable or disable the priority arguments in the relevant functions.
#define BS_THREAD_POOL_PRIORITY_INPUT , const priority_t priority = 0 #define BS_THREAD_POOL_PRIORITY_INPUT , const priority_t priority = 0
#define BS_THREAD_POOL_PRIORITY_OUTPUT , priority #define BS_THREAD_POOL_PRIORITY_OUTPUT , priority
#else #else
#define BS_THREAD_POOL_PRIORITY_INPUT #define BS_THREAD_POOL_PRIORITY_INPUT
#define BS_THREAD_POOL_PRIORITY_OUTPUT #define BS_THREAD_POOL_PRIORITY_OUTPUT
#endif #endif
/** /**
@@ -138,12 +151,12 @@ namespace this_thread {
/** /**
* @brief A `thread_local` object used to obtain information about the index of the current thread. * @brief A `thread_local` object used to obtain information about the index of the current thread.
*/ */
thread_local thread_info_index get_index; inline thread_local thread_info_index get_index;
/** /**
* @brief A `thread_local` object used to obtain information about the thread pool that owns the current thread. * @brief A `thread_local` object used to obtain information about the thread pool that owns the current thread.
*/ */
thread_local thread_info_pool get_pool; inline thread_local thread_info_pool get_pool;
} // namespace this_thread } // namespace this_thread
/** /**
@@ -562,19 +575,19 @@ public:
*/ */
void reset(const concurrency_t num_threads, const std::function<void()>& init_task) void reset(const concurrency_t num_threads, const std::function<void()>& init_task)
{ {
std::unique_lock tasks_lock(tasks_mutex);
#ifdef BS_THREAD_POOL_ENABLE_PAUSE #ifdef BS_THREAD_POOL_ENABLE_PAUSE
std::unique_lock tasks_lock(tasks_mutex);
const bool was_paused = paused; const bool was_paused = paused;
paused = true; paused = true;
#endif
tasks_lock.unlock(); tasks_lock.unlock();
#endif
wait(); wait();
destroy_threads(); destroy_threads();
thread_count = determine_thread_count(num_threads); thread_count = determine_thread_count(num_threads);
threads = std::make_unique<std::thread[]>(thread_count); threads = std::make_unique<std::thread[]>(thread_count);
create_threads(init_task); create_threads(init_task);
tasks_lock.lock();
#ifdef BS_THREAD_POOL_ENABLE_PAUSE #ifdef BS_THREAD_POOL_ENABLE_PAUSE
tasks_lock.lock();
paused = was_paused; paused = was_paused;
#endif #endif
} }
@@ -595,8 +608,10 @@ public:
detach_task( detach_task(
[task = std::forward<F>(task), task_promise] [task = std::forward<F>(task), task_promise]
{ {
#ifndef BS_THREAD_POOL_DISABLE_EXCEPTION_HANDLING
try try
{ {
#endif
if constexpr (std::is_void_v<R>) if constexpr (std::is_void_v<R>)
{ {
task(); task();
@@ -606,6 +621,7 @@ public:
{ {
task_promise->set_value(task()); task_promise->set_value(task());
} }
#ifndef BS_THREAD_POOL_DISABLE_EXCEPTION_HANDLING
} }
catch (...) catch (...)
{ {
@@ -617,6 +633,7 @@ public:
{ {
} }
} }
#endif
} BS_THREAD_POOL_PRIORITY_OUTPUT); } BS_THREAD_POOL_PRIORITY_OUTPUT);
return task_promise->get_future(); return task_promise->get_future();
} }
@@ -731,9 +748,9 @@ public:
// Macros used internally to enable or disable pausing in the waiting and worker functions. // Macros used internally to enable or disable pausing in the waiting and worker functions.
#ifdef BS_THREAD_POOL_ENABLE_PAUSE #ifdef BS_THREAD_POOL_ENABLE_PAUSE
#define BS_THREAD_POOL_PAUSED_OR_EMPTY (paused || tasks.empty()) #define BS_THREAD_POOL_PAUSED_OR_EMPTY (paused || tasks.empty())
#else #else
#define BS_THREAD_POOL_PAUSED_OR_EMPTY tasks.empty() #define BS_THREAD_POOL_PAUSED_OR_EMPTY tasks.empty()
#endif #endif
/** /**
@@ -952,8 +969,8 @@ private:
const size_t total_size = static_cast<size_t>(index_after_last - first_index); const size_t total_size = static_cast<size_t>(index_after_last - first_index);
if (num_blocks > total_size) if (num_blocks > total_size)
num_blocks = total_size; num_blocks = total_size;
block_size = static_cast<size_t>(total_size / num_blocks); block_size = total_size / num_blocks;
remainder = static_cast<size_t>(total_size % num_blocks); remainder = total_size % num_blocks;
if (block_size == 0) if (block_size == 0)
{ {
block_size = 1; block_size = 1;
@@ -1136,3 +1153,4 @@ private:
bool workers_running = false; bool workers_running = false;
}; // class thread_pool }; // class thread_pool
} // namespace BS } // namespace BS
#endif
+11 -9
View File
@@ -1,16 +1,15 @@
#pragma once #ifndef BS_THREAD_POOL_UTILS_HPP
#define BS_THREAD_POOL_UTILS_HPP
/** /**
* @file BS_thread_pool_utils.hpp * @file BS_thread_pool_utils.hpp
* @author Barak Shoshany (baraksh@gmail.com) (http://baraksh.com) * @author Barak Shoshany (baraksh@gmail.com) (https://baraksh.com)
* @version 4.0.0 * @version 4.1.0
* @date 2023-12-27 * @date 2024-03-22
* @copyright Copyright (c) 2023 Barak Shoshany. Licensed under the MIT license. If you found this project useful, please consider starring it on GitHub! If you use this library in software of any kind, please provide a link to the GitHub repository https://github.com/bshoshany/thread-pool in the source code and documentation. If you use this library in published research, please cite it as follows: Barak Shoshany, "A C++17 Thread Pool for High-Performance Scientific Computing", doi:10.5281/zenodo.4742687, arXiv:2105.00613 (May 2021) * @copyright Copyright (c) 2024 Barak Shoshany. Licensed under the MIT license. If you found this project useful, please consider starring it on GitHub! If you use this library in software of any kind, please provide a link to the GitHub repository https://github.com/bshoshany/thread-pool in the source code and documentation. If you use this library in published research, please cite it as follows: Barak Shoshany, "A C++17 Thread Pool for High-Performance Scientific Computing", doi:10.1016/j.softx.2024.101687, SoftwareX 26 (2024) 101687, arXiv:2105.00613
* *
* @brief BS::thread_pool: a fast, lightweight, and easy-to-use C++17 thread pool library. This header file contains independent utility classes that are part of the library, but are not needed to use the thread pool itself. * @brief BS::thread_pool: a fast, lightweight, and easy-to-use C++17 thread pool library. This header file contains independent utility classes that are part of the library, but are not needed to use the thread pool itself.
*/ */
#include <atomic> // std::atomic
#include <chrono> // std::chrono #include <chrono> // std::chrono
#include <future> // std::promise, std::shared_future #include <future> // std::promise, std::shared_future
#include <initializer_list> // std::initializer_list #include <initializer_list> // std::initializer_list
@@ -24,8 +23,10 @@
* @brief A namespace used by Barak Shoshany's projects. * @brief A namespace used by Barak Shoshany's projects.
*/ */
namespace BS { namespace BS {
// A macro containing the version of the thread pool utilities library. // Macros indicating the version of the thread pool utilities library.
#define BS_THREAD_POOL_UTILS_VERSION "v4.0.0 (2023-12-27)" #define BS_THREAD_POOL_UTILS_VERSION_MAJOR 4
#define BS_THREAD_POOL_UTILS_VERSION_MINOR 1
#define BS_THREAD_POOL_UTILS_VERSION_PATCH 0
/** /**
* @brief A utility class to allow simple signalling between threads. * @brief A utility class to allow simple signalling between threads.
@@ -199,3 +200,4 @@ private:
std::chrono::duration<double> elapsed_time = std::chrono::duration<double>::zero(); std::chrono::duration<double> elapsed_time = std::chrono::duration<double>::zero();
}; // class timer }; // class timer
} // namespace BS } // namespace BS
#endif
+58 -24
View File
@@ -1,9 +1,9 @@
/** /**
* @file BS_thread_pool_test.cpp * @file BS_thread_pool_test.cpp
* @author Barak Shoshany (baraksh@gmail.com) (http://baraksh.com) * @author Barak Shoshany (baraksh@gmail.com) (https://baraksh.com)
* @version 4.0.0 * @version 4.1.0
* @date 2023-12-27 * @date 2024-03-22
* @copyright Copyright (c) 2023 Barak Shoshany. Licensed under the MIT license. If you found this project useful, please consider starring it on GitHub! If you use this library in software of any kind, please provide a link to the GitHub repository https://github.com/bshoshany/thread-pool in the source code and documentation. If you use this library in published research, please cite it as follows: Barak Shoshany, "A C++17 Thread Pool for High-Performance Scientific Computing", doi:10.5281/zenodo.4742687, arXiv:2105.00613 (May 2021) * @copyright Copyright (c) 2024 Barak Shoshany. Licensed under the MIT license. If you found this project useful, please consider starring it on GitHub! If you use this library in software of any kind, please provide a link to the GitHub repository https://github.com/bshoshany/thread-pool in the source code and documentation. If you use this library in published research, please cite it as follows: Barak Shoshany, "A C++17 Thread Pool for High-Performance Scientific Computing", doi:10.1016/j.softx.2024.101687, SoftwareX 26 (2024) 101687, arXiv:2105.00613
* *
* @brief BS::thread_pool: a fast, lightweight, and easy-to-use C++17 thread pool library. This program tests all aspects of the library, but is not needed in order to use the library. * @brief BS::thread_pool: a fast, lightweight, and easy-to-use C++17 thread pool library. This program tests all aspects of the library, but is not needed in order to use the library.
*/ */
@@ -25,7 +25,6 @@
#include <mutex> // std::mutex, std::scoped_lock #include <mutex> // std::mutex, std::scoped_lock
#include <random> // std::mt19937_64, std::random_device, std::uniform_int_distribution #include <random> // std::mt19937_64, std::random_device, std::uniform_int_distribution
#include <sstream> // std::ostringstream #include <sstream> // std::ostringstream
#include <stdexcept> // std::runtime_error
#include <string> // std::string, std::to_string #include <string> // std::string, std::to_string
#include <string_view> // std::string_view #include <string_view> // std::string_view
#include <thread> // std::this_thread, std::thread #include <thread> // std::this_thread, std::thread
@@ -33,22 +32,40 @@
#include <utility> // std::as_const, std::forward, std::move, std::pair #include <utility> // std::as_const, std::forward, std::move, std::pair
#include <vector> // std::vector #include <vector> // std::vector
#if defined(__APPLE__) // By default, the test program enables all the optional features by defining the suitable macros, so it can test them. However, if the macro `BS_THREAD_POOL_LIGHT_TEST` is defined during compilation, the optional features will not be tested, and in addition, exception handling will be disabled.
#include <exception> // std::terminate #ifndef BS_THREAD_POOL_LIGHT_TEST
#define BS_THREAD_POOL_ENABLE_NATIVE_HANDLES
#define BS_THREAD_POOL_ENABLE_PAUSE
#define BS_THREAD_POOL_ENABLE_PRIORITY
#define BS_THREAD_POOL_ENABLE_WAIT_DEADLOCK_CHECK
#else
#define BS_THREAD_POOL_DISABLE_EXCEPTION_HANDLING
#endif #endif
// By default, the test program enables all the optional features by defining the suitable macros, so it can test them. However, if the macro `BS_THREAD_POOL_LIGHT_TEST` is defined during compilation, the optional features will not be tested. #ifndef BS_THREAD_POOL_DISABLE_EXCEPTION_HANDLING
#ifndef BS_THREAD_POOL_LIGHT_TEST #include <stdexcept> // std::runtime_error
#define BS_THREAD_POOL_ENABLE_NATIVE_HANDLES #if defined(__APPLE__)
#define BS_THREAD_POOL_ENABLE_PAUSE #include <exception> // std::terminate
#define BS_THREAD_POOL_ENABLE_PRIORITY #endif
#define BS_THREAD_POOL_ENABLE_WAIT_DEADLOCK_CHECK
#endif #endif
// Include the header files for the thread pool library and its utilities. // Include the header files for the thread pool library and its utilities.
#include "BS_thread_pool.hpp" #include "BS_thread_pool.hpp"
#include "BS_thread_pool_utils.hpp" #include "BS_thread_pool_utils.hpp"
// Macros indicating the version of the thread pool test program.
#define BS_THREAD_POOL_TEST_VERSION_MAJOR 4
#define BS_THREAD_POOL_TEST_VERSION_MINOR 1
#define BS_THREAD_POOL_TEST_VERSION_PATCH 0
#if (BS_THREAD_POOL_TEST_VERSION_MAJOR != BS_THREAD_POOL_VERSION_MAJOR || BS_THREAD_POOL_TEST_VERSION_MINOR != BS_THREAD_POOL_VERSION_MINOR || BS_THREAD_POOL_TEST_VERSION_PATCH != BS_THREAD_POOL_VERSION_PATCH)
#error The versions of BS_thread_pool_test.cpp and BS_thread_pool.hpp do not match. Aborting compilation.
#endif
#if (BS_THREAD_POOL_TEST_VERSION_MAJOR != BS_THREAD_POOL_UTILS_VERSION_MAJOR || BS_THREAD_POOL_TEST_VERSION_MINOR != BS_THREAD_POOL_UTILS_VERSION_MINOR || BS_THREAD_POOL_TEST_VERSION_PATCH != BS_THREAD_POOL_UTILS_VERSION_PATCH)
#error The versions of BS_thread_pool_test.cpp and BS_thread_pool_utils.hpp do not match. Aborting compilation.
#endif
using int64 = std::int_fast64_t; using int64 = std::int_fast64_t;
using std::size_t; using std::size_t;
@@ -1634,6 +1651,7 @@ void check_purge()
check(no_flags_set(flags)); check(no_flags_set(flags));
} }
#ifndef BS_THREAD_POOL_DISABLE_EXCEPTION_HANDLING
// ====================================== // ======================================
// Functions to verify exception handling // Functions to verify exception handling
// ====================================== // ======================================
@@ -1696,6 +1714,7 @@ void check_exceptions_multi_future()
} }
check(caught); check(caught);
} }
#endif
// ===================================== // =====================================
// Functions to verify vector operations // Functions to verify vector operations
@@ -1945,7 +1964,7 @@ void check_get_pool()
dual_println("Checking that all threads report the correct pool..."); dual_println("Checking that all threads report the correct pool...");
std::vector<std::atomic<BS::thread_pool*>> thread_pool_ptrs1(std::thread::hardware_concurrency()); std::vector<std::atomic<BS::thread_pool*>> thread_pool_ptrs1(std::thread::hardware_concurrency());
std::vector<std::atomic<BS::thread_pool*>> thread_pool_ptrs2(std::thread::hardware_concurrency()); std::vector<std::atomic<BS::thread_pool*>> thread_pool_ptrs2(std::thread::hardware_concurrency());
auto store_pointers = [](std::vector<std::atomic<BS::thread_pool*>>& ptrs) const std::function<void(std::vector<std::atomic<BS::thread_pool*>>&)> store_pointers = [](std::vector<std::atomic<BS::thread_pool*>>& ptrs)
{ {
BS::this_thread::optional_pool ptr = BS::this_thread::get_pool(); BS::this_thread::optional_pool ptr = BS::this_thread::get_pool();
if (ptr.has_value()) if (ptr.has_value())
@@ -1965,7 +1984,7 @@ void check_get_pool()
}); });
pool1.wait(); pool1.wait();
pool2.wait(); pool2.wait();
auto check_pointers = [](const std::vector<std::atomic<BS::thread_pool*>>& ptrs, const BS::thread_pool& pool) const std::function<void(std::vector<std::atomic<BS::thread_pool*>>&, BS::thread_pool&)> check_pointers = [](const std::vector<std::atomic<BS::thread_pool*>>& ptrs, const BS::thread_pool& pool)
{ {
bool correct = true; bool correct = true;
for (const std::atomic<BS::thread_pool*>& ptr : ptrs) for (const std::atomic<BS::thread_pool*>& ptr : ptrs)
@@ -2244,32 +2263,43 @@ void check_performance()
void show_intro() void show_intro()
{ {
dual_println("BS::thread_pool: a fast, lightweight, and easy-to-use C++17 thread pool library"); dual_println("BS::thread_pool: a fast, lightweight, and easy-to-use C++17 thread pool library");
dual_println("(c) 2023 Barak Shoshany (baraksh@gmail.com) (http://baraksh.com)"); dual_println("(c) 2024 Barak Shoshany (baraksh@gmail.com) (https://baraksh.com)");
dual_println("GitHub: https://github.com/bshoshany/thread-pool"); dual_println("GitHub: https://github.com/bshoshany/thread-pool");
dual_println(); dual_println();
dual_println("Thread pool library version is ", BS_THREAD_POOL_VERSION, "."); dual_println("Thread pool library version is ", BS_THREAD_POOL_VERSION_MAJOR, '.', BS_THREAD_POOL_VERSION_MINOR, '.', BS_THREAD_POOL_VERSION_PATCH, '.');
dual_println("Hardware concurrency is ", std::thread::hardware_concurrency(), "."); dual_println("Thread pool utilities library version is ", BS_THREAD_POOL_UTILS_VERSION_MAJOR, '.', BS_THREAD_POOL_UTILS_VERSION_MINOR, '.', BS_THREAD_POOL_UTILS_VERSION_PATCH, '.');
dual_println("Hardware concurrency is ", std::thread::hardware_concurrency(), '.');
dual_println(); dual_println();
dual_print("Exception handling is ");
#ifndef BS_THREAD_POOL_DISABLE_EXCEPTION_HANDLING
dual_println("enabled.");
#else
dual_println("disabled.");
#endif
dual_print("Native handles are "); dual_print("Native handles are ");
#ifdef BS_THREAD_POOL_ENABLE_NATIVE_HANDLES #ifdef BS_THREAD_POOL_ENABLE_NATIVE_HANDLES
dual_println("enabled."); dual_println("enabled.");
#else #else
dual_println("disabled."); dual_println("disabled.");
#endif #endif
dual_print("Pausing is "); dual_print("Pausing is ");
#ifdef BS_THREAD_POOL_ENABLE_PAUSE #ifdef BS_THREAD_POOL_ENABLE_PAUSE
dual_println("enabled."); dual_println("enabled.");
#else #else
dual_println("disabled."); dual_println("disabled.");
#endif #endif
dual_print("Priority is "); dual_print("Priority is ");
#ifdef BS_THREAD_POOL_ENABLE_PRIORITY #ifdef BS_THREAD_POOL_ENABLE_PRIORITY
dual_println("enabled."); dual_println("enabled.");
#else #else
dual_println("disabled."); dual_println("disabled.");
#endif #endif
dual_print("Wait deadlock checks are "); dual_print("Wait deadlock checks are ");
#ifdef BS_THREAD_POOL_ENABLE_WAIT_DEADLOCK_CHECK #ifdef BS_THREAD_POOL_ENABLE_WAIT_DEADLOCK_CHECK
dual_println("enabled."); dual_println("enabled.");
@@ -2279,8 +2309,8 @@ void show_intro()
dual_println(); dual_println();
dual_println("Detected OS: ", detect_os(), "."); dual_println("Detected OS: ", detect_os(), '.');
dual_println("Detected compiler: ", detect_compiler(), "."); dual_println("Detected compiler: ", detect_compiler(), '.');
dual_println(); dual_println();
dual_println("Important: Please do not run any other applications, especially multithreaded applications, in parallel with this test!"); dual_println("Important: Please do not run any other applications, especially multithreaded applications, in parallel with this test!");
@@ -2436,7 +2466,7 @@ int main(int argc, char* argv[])
#ifdef BS_THREAD_POOL_ENABLE_WAIT_DEADLOCK_CHECK #ifdef BS_THREAD_POOL_ENABLE_WAIT_DEADLOCK_CHECK
check_wait_self_deadlock(); check_wait_self_deadlock();
#else #else
print_header("NOTE: Wait deadlock checks disabled, skipping test."); print_header("NOTE: Wait deadlock checks disabled, skipping the corresponding test.");
#endif #endif
print_header("Checking detach_loop() and submit_loop():"); print_header("Checking detach_loop() and submit_loop():");
@@ -2455,15 +2485,19 @@ int main(int argc, char* argv[])
print_header("Checking pausing:"); print_header("Checking pausing:");
check_pausing(); check_pausing();
#else #else
print_header("NOTE: Pausing disabled, skipping test."); print_header("NOTE: Pausing disabled, skipping the corresponding test.");
#endif #endif
print_header("Checking purge():"); print_header("Checking purge():");
check_purge(); check_purge();
#ifndef BS_THREAD_POOL_DISABLE_EXCEPTION_HANDLING
print_header("Checking exception handling:"); print_header("Checking exception handling:");
check_exceptions_submit(); check_exceptions_submit();
check_exceptions_multi_future(); check_exceptions_multi_future();
#else
print_header("NOTE: Exception handling disabled, skipping the corresponding test.");
#endif
print_header("Checking parallelized vector operations:"); print_header("Checking parallelized vector operations:");
check_vectors(); check_vectors();
@@ -2472,7 +2506,7 @@ int main(int argc, char* argv[])
print_header("Checking task priority:"); print_header("Checking task priority:");
check_priority(); check_priority();
#else #else
print_header("NOTE: Task priority disabled, skipping test."); print_header("NOTE: Task priority disabled, skipping the corresponding test.");
#endif #endif
print_header("Checking thread initialization functions and get_index():"); print_header("Checking thread initialization functions and get_index():");
@@ -2516,7 +2550,7 @@ int main(int argc, char* argv[])
{ {
print_header("FAILURE: Passed " + std::to_string(tests_succeeded) + " checks, but failed " + std::to_string(tests_failed) + "!", '+'); print_header("FAILURE: Passed " + std::to_string(tests_succeeded) + " checks, but failed " + std::to_string(tests_failed) + "!", '+');
dual_println("\nPlease submit a bug report at https://github.com/bshoshany/thread-pool/issues including the exact specifications of your system (OS, CPU, compiler, etc.) and the generated log file."); dual_println("\nPlease submit a bug report at https://github.com/bshoshany/thread-pool/issues including the exact specifications of your system (OS, CPU, compiler, etc.) and the generated log file.");
#if defined(__APPLE__) #if defined(__APPLE__) && !defined(BS_THREAD_POOL_DISABLE_EXCEPTION_HANDLING)
// macOS does not implement `std::quick_exit` for some reason. `std::exit()` cannot be used here, as it might get stuck if a deadlock occurs. // macOS does not implement `std::quick_exit` for some reason. `std::exit()` cannot be used here, as it might get stuck if a deadlock occurs.
std::terminate(); std::terminate();
#else #else
+16 -12
View File
@@ -1,11 +1,15 @@
#!/usr/bin/env pwsh #!/usr/bin/env pwsh
# BS_thread_pool_test.ps1 <#
# By Barak Shoshany (baraksh@gmail.com) (http://baraksh.com) .SYNOPSIS
# v4.0.0, 2023-12-27 BS::thread_pool: a fast, lightweight, and easy-to-use C++17 thread pool library by Barak Shoshany (baraksh@gmail.com) (https://baraksh.com) v4.1.0 (2024-03-22)
# Copyright (c) 2023 Barak Shoshany. Licensed under the MIT license. If you found this project useful, please consider starring it on GitHub! If you use this library in software of any kind, please provide a link to the GitHub repository https://github.com/bshoshany/thread-pool in the source code and documentation. If you use this library in published research, please cite it as follows: Barak Shoshany, "A C++17 Thread Pool for High-Performance Scientific Computing", doi:10.5281/zenodo.4742687, arXiv:2105.00613 (May 2021) .DESCRIPTION
# This script compiles and runs the bundled test program with different compilers.
# BS::thread_pool: a fast, lightweight, and easy-to-use C++17 thread pool library. This script compiles and runs the bundled test program with different compilers. .NOTES
Copyright (c) 2024 Barak Shoshany. Licensed under the MIT license. If you found this project useful, please consider starring it on GitHub! If you use this library in software of any kind, please provide a link to the GitHub repository https://github.com/bshoshany/thread-pool in the source code and documentation. If you use this library in published research, please cite it as follows: Barak Shoshany, "A C++17 Thread Pool for High-Performance Scientific Computing", doi:10.1016/j.softx.2024.101687, SoftwareX 26 (2024) 101687, arXiv:2105.00613
.LINK
https://github.com/bshoshany/thread-pool
#>
Set-StrictMode -Version Latest Set-StrictMode -Version Latest
@@ -119,10 +123,10 @@ $ExePrefix = 'BS_thread_pool_test_'
$Executables = @() $Executables = @()
Function Build-ClangGCC([String] $Compiler, [String] $ExeSuffix, [String] $Macros = '') Function Build-ClangGCC([String] $Compiler, [String] $ExeSuffix, [String] $ExtraFlags = '')
{ {
$FullExe = Join-Path $BuildFolder "$ExePrefix$ExeSuffix$Extension" $FullExe = Join-Path $BuildFolder "$ExePrefix$ExeSuffix$Extension"
$Command = "$Compiler $SourceFile$PThread -I../include -std=c++17 -O3 -march=native -Wall -Wextra -Wconversion -Wsign-conversion -Wpedantic -Weffc++ -Wshadow -o $FullExe $Macros" $Command = "$Compiler $SourceFile$PThread -I../include -std=c++17 -O3 -march=native -Wall -Wextra -Wconversion -Wsign-conversion -Wpedantic -Weffc++ -Wshadow -o $FullExe $ExtraFlags"
Write-Command $Command Write-Command $Command
Invoke-Expression $Command Invoke-Expression $Command
If ($LASTEXITCODE) If ($LASTEXITCODE)
@@ -153,8 +157,8 @@ Write-Host
If (Get-Command 'g++' -ErrorAction SilentlyContinue) If (Get-Command 'g++' -ErrorAction SilentlyContinue)
{ {
Write-Text 'Compiling with GCC...' Write-Text 'Compiling with GCC...'
Build-ClangGCC 'g++' 'gcc' Build-ClangGCC 'g++' 'gcc' '-Wuseless-cast'
Build-ClangGCC 'g++' 'gcc_light' '-DBS_THREAD_POOL_LIGHT_TEST' Build-ClangGCC 'g++' 'gcc_light' '-Wuseless-cast -DBS_THREAD_POOL_LIGHT_TEST'
} }
Else Else
{ {
@@ -163,12 +167,12 @@ Else
Write-Host Write-Host
Function Build-MSVC([String] $ExeSuffix, [String] $Macros = '') Function Build-MSVC([String] $ExeSuffix, [String] $ExtraFlags = '')
{ {
$MSVCName = "$ExePrefix$ExeSuffix" $MSVCName = "$ExePrefix$ExeSuffix"
$FullExe = Join-Path $BuildFolder "$MSVCName$Extension" $FullExe = Join-Path $BuildFolder "$MSVCName$Extension"
$FullObj = Join-Path $BuildFolder "$MSVCName.obj" $FullObj = Join-Path $BuildFolder "$MSVCName.obj"
$Env:BS_THREAD_POOL_MSVC_COMMAND = "cl $SourceFile /I../include /std:c++17 /permissive- /O2 /W4 /EHsc /Fe:$FullExe /Fo:$FullObj $Macros" $Env:BS_THREAD_POOL_MSVC_COMMAND = "cl $SourceFile /I../include /std:c++17 /permissive- /O2 /W4 /EHsc /Fe:$FullExe /Fo:$FullObj $ExtraFlags"
Write-Command $Env:BS_THREAD_POOL_MSVC_COMMAND Write-Command $Env:BS_THREAD_POOL_MSVC_COMMAND
pwsh -Command { pwsh -Command {
$CurrentDir = Get-Location $CurrentDir = Get-Location