[3718] | 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
|
---|