Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit fa2a48a

Browse files
updated README
1 parent c6787cf commit fa2a48a

File tree

1 file changed

+27
-31
lines changed

1 file changed

+27
-31
lines changed

README.md

Lines changed: 27 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -62,8 +62,8 @@ for adapting to this new change.
6262
# Table of Contents
6363

6464
* [Get Started with Cpp-Taskflow](#get-started-with-cpp-taskflow)
65-
* [Create a Taskflow Graph](#create-a-taskflow-graph)
66-
* [Step 1: Create a Task](#step-1-create-a-task)
65+
* [Create a Taskflow Application](#create-a-taskflow-application)
66+
* [Step 1: Create a Taskflow](#step-1-create-a-taskflow)
6767
* [Step 2: Define Task Dependencies](#step-2-define-task-dependencies)
6868
* [Step 3: Execute a Taskflow](#step-3-execute-a-taskflow)
6969
* [Dynamic Tasking](#dynamic-tasking)
@@ -154,12 +154,12 @@ b1.precede(T); // b1 runs before T
154154
b3.precede(T); // b3 runs before T
155155
```
156156

157-
# Create a Taskflow Graph
157+
# Create a Taskflow Application
158158

159159
Cpp-Taskflow defines a very expressive API to create task dependency graphs.
160160
Most applications are developed through the following three steps.
161161

162-
## Step 1: Create a Task
162+
## Step 1: Create a Taskflow
163163

164164
Create a taskflow object to build a task dependency graph:
165165

@@ -187,8 +187,8 @@ auto [A, B, C, D] = taskflow.emplace(
187187

188188
## Step 2: Define Task Dependencies
189189

190-
You can add dependency links between tasks to enforce one task run after another.
191-
The dependency links must be specified in a
190+
You can add dependency links between tasks to enforce one task to run after another.
191+
The dependency graph must be a
192192
[Directed Acyclic Graph (DAG)](https://en.wikipedia.org/wiki/Directed_acyclic_graph).
193193
The handle `Task` supports different methods for you to describe task dependencies.
194194

@@ -209,12 +209,12 @@ An executor manages a set of worker threads to execute a taskflow
209209
through an efficient *work-stealing* algorithm.
210210

211211
```cpp
212-
tf::Executor executor;
212+
tf::Executor executor;
213213
```
214214

215215
The executor provides a rich set of methods to run a taskflow.
216-
You can run a taskflow one or multiple times, or until a stopping criteria is met.
217-
These methods are non-blocking and all return a [std::future][std::future]
216+
You can run a taskflow multiple times, or until a stopping criteria is met.
217+
These methods are non-blocking with a [std::future][std::future] return
218218
to let you query the execution status.
219219

220220
```cpp
@@ -247,7 +247,7 @@ each representing a specific part of your parallel decomposition.
247247
# Dynamic Tasking
248248

249249
Another powerful feature of Taskflow is *dynamic* tasking.
250-
Dynamic tasks are those created during the execution of a taskflow.
250+
Dynamic tasks are those tasks created during the execution of a taskflow.
251251
These tasks are spawned by a parent task and are grouped together to a *subflow* graph.
252252
The example below demonstrates how to create a subflow
253253
that spawns three tasks at runtime.
@@ -275,9 +275,9 @@ B.precede(D); // D runs after B
275275
C.precede(D); // D runs after C
276276
```
277277

278-
By default, a subflow graph joins to its parent node.
279-
This guarantees a subflow graph to finish before the successors of
280-
its parent node.
278+
By default, a subflow graph joins its parent node.
279+
This ensures a subflow graph finishes before the successors of
280+
its parent task.
281281
You can disable this feature by calling `subflow.detach()`.
282282
For example, detaching the above subflow will result in the following execution flow:
283283

@@ -391,7 +391,7 @@ A.precede(B);
391391

392392
When a subflow is detached from its parent task, it becomes a parallel
393393
execution line to the current flow graph and will eventually
394-
join to the same taskflow.
394+
join the same taskflow.
395395

396396
<img align="right" src="image/detached_subflow_future.png" width="25%">
397397

@@ -445,27 +445,21 @@ f2B.precede(f1_module_task);
445445
f1_module_task.precede(f2C);
446446
```
447447
448-
Similarly, `composed_of` returns a task handle and you can use the same methods
448+
Similarly, `composed_of` returns a task handle and you can use the methods
449449
`precede` and `gather` to create dependencies.
450450
You can compose a taskflow from multiple taskflows and use the result
451-
to compose another taskflow and so on.
452-
453-
451+
to compose a larger taskflow and so on.
454452
455453
# Debug a Taskflow Graph
456454
457455
Concurrent programs are notoriously difficult to debug.
458-
Cpp-Taskflow leverages the graph properties to relieve the debugging pain.
459-
To debug a taskflow graph,
460-
(1) name tasks and dump the graph, and
456+
To debug a taskflow graph, we suggest:
457+
(1) name each task and dump the graph, and
461458
(2) start with one thread before going multiple.
462-
Currently, Cpp-Taskflow supports [GraphViz][GraphViz] format.
463459
464460
## Dump a Taskflow Graph
465461
466-
Each time you create a task or add a dependency,
467-
it adds a node or an edge to the taskflow graph.
468-
You can dump it to a GraphViz format using the method `dump`.
462+
You can dump a taskflow in [GraphViz][GraphViz] format using the method `dump`.
469463
470464
```cpp
471465
// debug.cpp
@@ -508,7 +502,7 @@ digraph Taskflow {
508502

509503
When you have dynamic tasks (subflows),
510504
you cannot simply use the `dump` method because it displays only the static portion.
511-
Instead, you need to execute the graph to spawn dynamic tasks first.
505+
Instead, you need to execute the graph first to spawn dynamic tasks.
512506

513507
<img align="right" src="image/debug_subflow.png" width="25%">
514508

@@ -527,8 +521,8 @@ tf::Task B = taskflow.emplace([] (tf::Subflow& subflow) {
527521

528522
A.precede(B);
529523

530-
executor.run(tf).get(); // run the taskflow
531-
tf.dump(std::cout); // dump the graph including dynamic tasks
524+
executor.run(tf).wait(); // run the taskflow
525+
tf.dump(std::cout); // dump the graph including dynamic tasks
532526
```
533527

534528
# Monitor Thread Activities
@@ -699,7 +693,7 @@ The method `transform_reduce` is similar to reduce, except it applies a unary op
699693
This is particular useful when you need additional data processing to reduce a range of elements.
700694

701695
```cpp
702-
std::vector<std::pari<int, int>> v = { {1, 5}, {6, 4}, {-6, 4} };
696+
std::vector<std::pair<int, int>> v = { {1, 5}, {6, 4}, {-6, 4} };
703697
int min = std::numeric_limits<int>::max();
704698
auto [S, T] = tf.transform_reduce(v.begin(), v.end(), min,
705699
[] (int l, int r) { return std::min(l, r); },
@@ -822,6 +816,7 @@ thousands of task nodes and links, there are a few amateur pitfalls and mistakes
822816
+ Having a cycle in a graph may result in running forever
823817
+ Destructing a taskflow while it is running in one execution results in undefined behavior
824818
+ Trying to modify a running task can result in undefined behavior
819+
+ Touching a taskflow or an executor from multiple threads is not safe
825820

826821
Cpp-Taskflow is known to work on Linux distributions, MAC OSX, and Microsoft Visual Studio.
827822
Please [let me know][email me] if you found any issues in a particular platform.
@@ -914,12 +909,13 @@ Cpp-Taskflow is being actively developed and contributed by the following people
914909
- [Glen Fraser](https://github.com/totalgee) created a standalone C++14-compatible [threadpool](./taskflow/threadpool/threadpool_cxx14.hpp) for taskflow; various other fixes and examples
915910
- [Guannan Guo](https://github.com/gguo4) added different threadpool implementations to enhance the performance for taskflow
916911
- [Patrik Huber][Patrik Huber] helped fixed typos in the documentation
917-
- [ForgeMistress][ForgeMistress] provided API ideas about sharing the executor to avoid thread over-subscriptiong issues
912+
- [ForgeMistress][ForgeMistress] provided API ideas about sharing the executor to avoid thread over-subscription issues
918913
- [Alexander Neumann](https://github.com/Neumann-A) helped modify the cmake build to make Cpp-Taskflow importable from external cmake projects
919914
- [Paolo Bolzoni](https://github.com/paolobolzoni) helped remove extraneous semicolons to suppress extra warning during compilation and contributed to a dataflow example
920915
- [Pursche](https://github.com/Pursche) fixed compilation warning on Microsoft Visual Studio
921916
- [KingDuckZ][KingDuckZ] helped discover the memory leak in the memory allocator used in graph and topology
922-
- [mrogez-yseop](https://github.com/mrogez-yseop) helped fix the missing comma in outputing the execution timeline JSON from the observer
917+
- [mrogez-yseop](https://github.com/mrogez-yseop) helped fix the missing comma in outputting the execution timeline JSON from the observer
918+
- [Sztergbaum Roman](https://github.com/Milerius) replaced the error-prone global setting in cmake with project-specific targets
923919

924920
Meanwhile, we appreciate the support from many organizations for our development on Cpp-Taskflow.
925921
Please [let me know][email me] if I forgot someone!

0 commit comments

Comments
 (0)