1 | // This may look like C code, but it is really -*- C++ -*-
|
---|
2 | // UPS - LAL (Orsay) / IN2P3/CNRS - IRFU/SPP (Saclay) / CEA
|
---|
3 | #ifndef PARLEX_SEEN
|
---|
4 | #define PARLEX_SEEN
|
---|
5 |
|
---|
6 | // Classes pour execution de taches paralleles en utilisant les threads
|
---|
7 | // R. Ansari UPS+LAL IN2P3/CNRS 2005
|
---|
8 |
|
---|
9 | #include "zthread.h"
|
---|
10 | #include <vector>
|
---|
11 |
|
---|
12 | namespace SOPHYA {
|
---|
13 | using namespace std;
|
---|
14 |
|
---|
15 | //--------------------------------------------------------------------
|
---|
16 | // Interface pour les objets ayant une fonction (Execute()) pouvant
|
---|
17 | // s'executer en parallele
|
---|
18 | //--------------------------------------------------------------------
|
---|
19 | /*!
|
---|
20 | \class ParallelTaskInterface
|
---|
21 | \ingroup SysTools
|
---|
22 | \brief Interface definition for parallel task object.
|
---|
23 |
|
---|
24 | The pure virtual method execute() should be redefined by the classes
|
---|
25 | inheriting from ParallelTaskInterface
|
---|
26 | */
|
---|
27 | class ParallelTaskInterface {
|
---|
28 | public:
|
---|
29 | explicit ParallelTaskInterface() { }
|
---|
30 | virtual ~ParallelTaskInterface() { }
|
---|
31 | /*! This method should perform the actual computation. The parameter tid
|
---|
32 | is used by the ParallelExecutor class to identify the thread calling the method
|
---|
33 | */
|
---|
34 | virtual int execute(int tid) = 0;
|
---|
35 | };
|
---|
36 |
|
---|
37 | //---- Implementation de ParallelTaskInterface pour l'execution des fonctions
|
---|
38 | typedef int (* ParalExFunction) (int);
|
---|
39 | //----
|
---|
40 | class ParallelTaskFunction {
|
---|
41 | public:
|
---|
42 | explicit ParallelTaskFunction(ParalExFunction f);
|
---|
43 | virtual int execute(int tid);
|
---|
44 |
|
---|
45 | ParalExFunction parfunc_;
|
---|
46 | };
|
---|
47 |
|
---|
48 | //--------------------------------------------------------------------
|
---|
49 | // Classe de thread permettant l'execution controle de la methode
|
---|
50 | // ParallelTaskInterface::Execute()
|
---|
51 | //--------------------------------------------------------------------
|
---|
52 | class ParalExThread : public ZThread {
|
---|
53 | public:
|
---|
54 | explicit ParalExThread(ParallelTaskInterface& ptask, int tid);
|
---|
55 | virtual void run();
|
---|
56 |
|
---|
57 | // demarre l'execution (start() doit etre appele avant)
|
---|
58 | //!
|
---|
59 | int go();
|
---|
60 | // Attend la fin de l'execution
|
---|
61 | int waitEndOfExecution();
|
---|
62 | // Termine (arrete) l'execution du thread . si fgwait==true, attend l'arret effectif du tread.
|
---|
63 | void terminate(bool fgwait=true);
|
---|
64 | // demarre l'execution et attend sa fin
|
---|
65 | //! Launches the execution of ptask_.execute() and waits for its ending.
|
---|
66 | inline int execute()
|
---|
67 | {
|
---|
68 | int rc=go();
|
---|
69 | if(rc!=0) return rc;
|
---|
70 | return waitEndOfExecution();
|
---|
71 | }
|
---|
72 | //! Return the the execution phase, 0: waiting, 1:go called, 2: executing, 3: execution finished
|
---|
73 | inline int getExecutionState() { return state_; }
|
---|
74 | //! Return true if an exception has been catched when ptask_.execute() called, and correspond message
|
---|
75 | inline bool IfException(string& msg)
|
---|
76 | { msg=msg_exc_; return fgexcept_; }
|
---|
77 |
|
---|
78 | //! Return reference to the parallel task object
|
---|
79 | inline ParallelTaskInterface& getParallelTask() { return ptask_; }
|
---|
80 | //! Set (changes) the parallel task object.
|
---|
81 | int setParallelTask(ParallelTaskInterface& ptask);
|
---|
82 | //! Return the rank or thread-id in a parallel execution context
|
---|
83 | inline int Rank() { return tid_; }
|
---|
84 |
|
---|
85 | protected:
|
---|
86 | ParallelTaskInterface& ptask_;
|
---|
87 | int tid_;
|
---|
88 | ZMutex mtx_;
|
---|
89 | int state_; // running state
|
---|
90 | // 0:idle, 1: go, 2: executing, 3: executionfinished , 6:terminatethread, 7:threadfinished
|
---|
91 | bool fgexcept_; // true -> exception lors de l'execution de ptask_.execute()
|
---|
92 | string msg_exc_; // message d'exception le cas echeant
|
---|
93 | };
|
---|
94 |
|
---|
95 | //--------------------------------------------------------------------
|
---|
96 | // Classe permettant l'execution simultanee de plusieurs fonctions
|
---|
97 | // ParallelTaskInterface::Execute()
|
---|
98 | //--------------------------------------------------------------------
|
---|
99 | class ParallelExecutor {
|
---|
100 | public:
|
---|
101 | explicit ParallelExecutor(ParallelTaskInterface& ptask, size_t nthr);
|
---|
102 | explicit ParallelExecutor(vector< ParallelTaskInterface * > vptask);
|
---|
103 | virtual ~ParallelExecutor();
|
---|
104 |
|
---|
105 | //! Set (changes) the parallel task objects (same object for all threads)
|
---|
106 | void SetParallelTask( ParallelTaskInterface& ptask );
|
---|
107 | //! Set (changes) the parallel task objects
|
---|
108 | void SetParallelTask( vector< ParallelTaskInterface * > vptask);
|
---|
109 |
|
---|
110 | //! Starts all the parallel threads
|
---|
111 | virtual void start();
|
---|
112 | // Appel a l'execution parallele
|
---|
113 | virtual int execute();
|
---|
114 | //! Return the number of parallel threads
|
---|
115 | inline size_t nThreads() { return vpext_.size(); }
|
---|
116 | //! Return RC for the ParalleTask.execute() of thread i
|
---|
117 | inline int getRC(size_t i) { return vrc_[i]; }
|
---|
118 | //! Return the execption condition for the ParalleTask.execute() of thread i
|
---|
119 | inline bool IfException(size_t i, string& msg) { return vpext_[i]->IfException(msg); }
|
---|
120 |
|
---|
121 | protected:
|
---|
122 | vector<ParalExThread *> vpext_;
|
---|
123 | vector<int> vrc_;
|
---|
124 | bool fgstarted_; // true -> les threads tournent (thr[i].start() appeles)
|
---|
125 | bool fgrunning_; // true -> en cours d'execution
|
---|
126 | };
|
---|
127 |
|
---|
128 | } // namespace SOPHYA
|
---|
129 |
|
---|
130 | #endif
|
---|