项目作者: DanIsraelMalta

项目描述 :
KISS style graph-based parallel task programing
高级语言: C++
项目地址: git://github.com/DanIsraelMalta/BabyTask.git
创建时间: 2020-05-11T18:10:46Z
项目社区:https://github.com/DanIsraelMalta/BabyTask

开源协议:MIT License

下载


BabyTask

Codacy Badge
Windows Build status

A (very) lightweight concurrent task based programing model.
I belive that simple usage examples can explain everything…

Simple ordered task graph using one thread

  1. // task1 -> task3 -> task2 -> task4
  2. // test string
  3. std::string out{};
  4. // task graph (notice that it has only one thread!)
  5. BabyTask::TaskGraph task_graph;
  6. // define tasks
  7. auto task1 = task_graph.makeTaskNode([&out]() -> void { out = "task1->"; });
  8. auto task2 = task_graph.makeTaskNode([&out]() -> void { out += "task2->"; });
  9. auto task3 = task_graph.makeTaskNode([&out]() -> void { out += "task3->"; });
  10. auto task4 = task_graph.makeTaskNode([&out]() -> void { out += "task4"; });
  11. // define task order
  12. task2->setParent(*task1);
  13. task4->setParent(*task1);
  14. task2->setParent(*task3);
  15. task4->setParent(*task3);
  16. task3->setParent(*task1);
  17. // no cycles in graph
  18. assert(task_graph.hasCycle() == false);
  19. // run task graph
  20. task_graph.execute();
  21. // check task graph order
  22. assert(out == "task1->task3->task2->task4");

Simple ordered task graph using one thread

  1. // task1 ---> task2 ----> task3 ---->
  2. // | | ---> task5
  3. // --------> task4 ---->
  4. // task1 also returns another variable which is not used else where in graph
  5. // locals
  6. std::int32_t num{};
  7. // task graph (1 thread)
  8. BabyTask::TaskGraph task_graph;
  9. // tasks
  10. std::function<int()> first = [&num]() -> int { num = 0; return 13; };
  11. auto task1 = task_graph.makeTaskNode(first);
  12. // can't use: auto task1 = task_graph.makeTaskNode([&num]() -> int { num = 0; return 13; });
  13. // since compiler will deduce it to be std::function<void()>
  14. auto task2 = task_graph.makeTaskNode([&num]() -> void { num = 1; });
  15. auto task3 = task_graph.makeTaskNode([&num]() -> void { num += 2; });
  16. auto task4 = task_graph.makeTaskNode([&num]() -> void { num *= 2; });
  17. auto task5 = task_graph.makeTaskNode([&num]() -> void { num %= 5; });
  18. // define task graph
  19. task2->setParent(*task1);
  20. task3->setParent(*task2);
  21. task4->setParent(*task2);
  22. task5->setParent(*task3);
  23. task5->setParent(*task4);
  24. // check that there are no cycles
  25. assert(task_graph.hasCycle() == false);
  26. // execute graph
  27. task_graph.execute();
  28. // check
  29. assert(task1->getValue() == 13);
  30. assert(num == 1);

Parallel ordered tasks:

  1. // task 1 ---> task 3 --- {tasks 1 and 3 run in parallel to tasks 2 and 4; but in a given order}
  2. // |-> task 5
  3. // task 2 ---> task 4 --- {tasks 2 and 4 run in parallel to tasks 1 and 3; but in a given order}
  4. // task graph (2 threads)
  5. BabyTask::TaskGraph task_graph(2);
  6. // locals
  7. std::vector<float> n0, n1;
  8. float n0_min{}, n1_max{}, average{35.13f};
  9. // task #1 - fill n0
  10. auto task1 = task_graph.makeTaskNode([&n0]() -> void {
  11. n0.resize(9'000'000);
  12. std::iota(n0.begin(), n0.end(), -4'500'000.0f);
  13. });
  14. // task #2 - fill n1
  15. auto task2 = task_graph.makeTaskNode([&n1]() -> void {
  16. n1.resize(9'000'000);
  17. std::iota(n1.begin(), n1.end(), -4'500'000.0f);
  18. });
  19. // task #3 - calculate n0 min number
  20. auto task3 = task_graph.makeTaskNode([&n0, &n0_min]() -> void {
  21. auto it = std::min_element(n0.begin(), n0.end());
  22. n0_min = *it;
  23. });
  24. // task #4 - calculate n1 max number
  25. auto task4 = task_graph.makeTaskNode([&n1, &n1_max]() -> void {
  26. auto it = std::max_element(n1.begin(), n1.end());
  27. n1_max = *it;
  28. });
  29. // task #5 - get average of task's 3 & 4 output
  30. auto task5 = task_graph.makeTaskNode([&n0_min, &n1_max, &average]() -> void {
  31. average = n0_min + 0.5f * (n1_max - n0_min);
  32. });
  33. // define task graph
  34. task3->setParent(*task1);
  35. task4->setParent(*task2);
  36. task5->setParent(*task4);
  37. task5->setParent(*task3);
  38. // check that there are no cycles
  39. assert(task_graph.hasCycle() == false);
  40. // execute graph
  41. task_graph.execute();
  42. // check
  43. assert(std::abs(static_cast<std::int32_t>(average * 10)) == 5);