SimultaneousFunctionSpawner.h
Go to the documentation of this file.
1 #ifndef cetlib_SimultaneousFunctionSpawner_h
2 #define cetlib_SimultaneousFunctionSpawner_h
3 
4 //=================================================================
5 // The 'SimultaneousFunctionSpawner' is intended for testing the
6 // behavior under simultaneous execution of a supplied functor. The
7 // functor can receive NO ARGUMENTS. This class should be used in the
8 // following pattern (e.g.):
9 //
10 // Using repeated tasks:
11 //
12 // std::atomic<unsigned> nTimesCalled {0u};
13 // auto count = [&counter]{ ++counter; };
14 // // Create 7 tasks of the function 'count'.
15 // cet::SimultaneousFunctionSpawner sps {cet::repeated_task(7u, count)};
16 // std::cout << nTimesCalled << '\n'; // Will print out '7'.
17 //
18 // Using separate tasks
19 //
20 // std::vector<std::function<void()>> tasks;
21 // std::vector<int> nums (2);
22 // tasks.push_back([&nums]{ nums[0] = 93; });
23 // tasks.push_back([&nums]{ nums[1] = 23; });
24 // cet::SimultaneousFunctionSpawner sps {tasks};
25 //
26 // The number of threads spawned is equan to the number of tasks
27 // supplied.
28 //
29 // The waiting mechanism here could be replaced with a
30 // condition_variable, similar to what Chris Green implemented in
31 // wirecap-libs/Barrier.hpp.
32 // =================================================================
33 
34 #include <atomic>
35 #include <thread>
36 #include <vector>
37 
38 namespace cet {
39 
40  template <typename F>
41  auto
42  repeated_task(std::size_t const nInstances, F func)
43  {
44  return std::vector<F>(nInstances, func);
45  }
46 
48  public:
49  template <typename FunctionToSpawn>
50  SimultaneousFunctionSpawner(std::vector<FunctionToSpawn> const& fs)
51  : counter_{fs.size()}
52  {
53  auto execute = [this](auto f) {
54  --counter_;
55  while (counter_ != 0)
56  ;
57  f();
58  };
59 
60  std::vector<std::thread> threads;
61  for (auto f : fs) {
62  threads.emplace_back(execute, f);
63  }
64 
65  for (auto& thread : threads)
66  thread.join();
67  }
68 
69  private:
70  std::atomic<std::size_t> counter_;
71  };
72 }
73 
74 #endif /* cetlib_SimultaneousFunctionSpawner_h */
75 
76 // Local variables:
77 // mode: c++
78 // End:
#define F(x, y, z)
double func(double x, double y)
def execute(command)
Definition: g4zmq.py:44
auto repeated_task(std::size_t const nInstances, F func)
SimultaneousFunctionSpawner(std::vector< FunctionToSpawn > const &fs)