source: Sophya/trunk/SophyaLib/SysTools/zthread.cc@ 4009

Last change on this file since 4009 was 3718, checked in by ansari, 16 years ago

1/ Corrections et modifications mineures ds ZThread, et ajout des classes

ParallelTaskInterface, ParalExThread, ParallelExecutor pour l'execution

de fonctions en parallele dans des threads, Reza 28/12/2009

File size: 6.7 KB
Line 
1// Interface C++ aux Thread POSIX - R. Ansari 02/2001
2// LAL (Orsay) / IN2P3-CNRS DAPNIA/SPP (Saclay) / CEA
3
4#include "sopnamsp.h"
5#include "zthread.h"
6#include <stdlib.h>
7#include <stdio.h>
8#include <string.h>
9#include <pthread.h>
10#include <signal.h>
11
12/*!
13 \class SOPHYA::ZThread
14 \ingroup SysTools
15 \brief Simple class for creating and controlling threads.
16
17 This class provides an interface for creating and controlling threads.
18 The implementation uses the POSIX thread interface.
19 The ZThread objects can be sub classed with the redefinition of
20 the \c run() method which then performs the task.
21 The default \c run() method of the base class can be used directly
22 to perform computation through a function (see \b setAction() method)
23 \sa SOPHYA::ZMutex
24 The following sample code shows the usage of ZThread object
25 to run simultaneously two functions to perform computation.
26
27 \code
28 // The functions to perform computing
29 void fun1(void *arg) { }
30 void fun2(void *arg) { }
31 // ...
32 ZThread zt1;
33 zt1.setAction(fun1, arg[1]);
34 ZThread zt2;
35 zt2.setAction(fun2, arg[1]);
36 cout << " Starting threads ... " << endl;
37 zt1.start();
38 zt2.start();
39 cout << " Waiting for threads to end ... " << endl;
40 zt1.join();
41 zt2.join();
42 \endcode
43*/
44
45#define CheckSt(st_, strg_) if (st_ != 0) perror(strg_);
46
47/*
48extern "C" {
49 void * zthr_run( void * xthr);
50 void zthr_sig_exit(int s);
51}
52*/
53
54static int _RCR_ = 99;
55static void * zthr_run(void * xthr)
56{
57 ZThread * thr = (ZThread *)xthr;
58 thr->run_p();
59 return &_RCR_;
60}
61
62static void zthr_cleanup(void * xthr)
63{
64 ZThread * thr = (ZThread *)xthr;
65 if(thr->_status == 2) thr->_status = 3;
66 return;
67}
68
69static int _RCS_ = 97;
70static void zthr_sig_exit(int s)
71{
72 printf("zthr_sig_exit(int s=%d) signal received -> pthread_exit()\n",s);
73 pthread_exit(&_RCS_);
74}
75
76/* ------ Classe ZThread ------- */
77/*!
78 Constructor, with optional specification of the thread stack size in bytes.
79 if not specified or zero, defaut system stack size is used.
80*/
81ZThread::ZThread(size_t stacksize)
82{
83 _status = 0;
84 _fgstarted = false;
85 _ssize = 0;
86 _act = NULL;
87 _usp = NULL;
88 _rc = -99;
89}
90
91ZThread::~ZThread()
92{
93 // Que faut-il faire ?
94}
95
96/*!
97 Method which starts the thread.
98 The thread object is created by a call to pthread_create() in this method.
99*/
100void ZThread::start()
101{
102 if ( _fgstarted ) throw ZThreadExc("ZThread::Start() - Already started thread !");
103 _fgstarted = true;
104 _status = 1;
105 int rc;
106 pthread_attr_t tha;
107 rc = pthread_attr_init(&tha);
108 CheckSt(rc,"ZThread::start() - Pb creating tha attribute object");
109 if (_ssize > 0)
110 rc = pthread_attr_setstacksize(&tha, _ssize);
111 rc = pthread_create(&_thr, &tha, zthr_run, this);
112 CheckSt(rc,"ZThread::start() - Pb creating the thread object");
113 setRC(rc);
114}
115
116/*!
117 Calls the pthread_cancel. Can be used to stop a running thread.
118*/
119void ZThread::cancel()
120{
121 if ( !IfStarted() ) throw ZThreadExc("ZThread::cancel() - thread not started !");
122 int rc = pthread_cancel(_thr);
123 CheckSt(rc,"ZThread::cancel() - Pb pthread_cancel() ");
124 setRC(-77);
125}
126
127/*!
128 Calls the pthread_kill to deliver a signal to the corresponding thread
129*/
130void ZThread::kill(int sig)
131{
132 if ( !IfStarted() ) throw ZThreadExc("ZThread::kill() - thread not started !");
133 int rc = pthread_kill(_thr, sig);
134 CheckSt(rc,"ZThread::kill() - Pb pthread_kill() ");
135 setRC(-76);
136}
137
138
139/*!
140 \brief Waits for the thread to terminate (call pthread_join() )
141*/
142void ZThread::join()
143{
144 if ( !IfStarted() ) throw ZThreadExc("ZThread::join() - thread not started !");
145 void * x;
146 int rc = pthread_join(_thr, &x);
147 CheckSt(rc,"ZThread::Join() - Pb pthread_join() ");
148 return;
149}
150
151/*!
152 \brief Method which does the actual computation
153 This virtual method can be redefined in the derived class, in order
154 to perform the actual computation. The default implementation call
155 the action function (if defined by setAction() )
156
157*/
158void ZThread::run()
159{
160 if (_act) _act(_usp);
161 exit(0);
162 return;
163}
164
165/*!
166 \brief Method called by the function passed to pthread_create().
167 This method sets the clean-up handler, changes the status variable
168 and call the run() method, and pthread_exit() at the end.
169*/
170void ZThread::run_p()
171{
172 _status = 2;
173 pthread_cleanup_push(zthr_cleanup, (void *)this);
174 run();
175 _status = 3;
176 pthread_exit(&(_rc));
177 pthread_cleanup_pop(0);
178 return;
179}
180
181
182void ZThread::ActivateExitOnSignal(int sig)
183{
184 struct sigaction ae, ad;
185
186 ae.sa_handler = zthr_sig_exit;
187 ad.sa_handler = SIG_DFL;
188 memset( &(ae.sa_mask), 0, sizeof(sigset_t) );
189 ae.sa_flags = 0;
190 memset( &(ad.sa_mask), 0, sizeof(sigset_t) );
191 ad.sa_flags = 0;
192#ifdef OSF1
193 ae.sa_flags = SA_RESTART;
194 ad.sa_mask = 0;
195#endif
196 printf(" Activating signal %d handling for threads -> pthread_exit()\n",sig);
197 sigaction(sig, &ae, NULL);
198}
199
200
201/* ------ Classe ZMutex ------- */
202/*!
203 \class SOPHYA::ZMutex
204 \ingroup SysTools
205 \brief Wrapper for a pair of (Mutex,Cond.Var) objects.
206
207 This class implements an interface to the Mutual Exclusion objects
208 of the POSIX threads.
209 The ZMutex objects should be used to control acces from different threads
210 to common objects through the \b lock() and \b unlock() methods.
211 When the \b signal() method is called, one of the waiting threads
212 on the corresponding mutex object (\b ZMutex::wait()) is awakened.
213 All waiting threads on the mutex object are awakened when \b broadcast()
214 is called.
215 \sa SOPHYA::ZSync
216*/
217
218/*!
219 Constructor: Creates an associated pair of POSIX \c pthread_mutex_t
220 and \c pthread_cond_t objects
221 \param : if fgd == true , the destructor call pthread_mutex_destroy/pthread_cond_destroy
222*/
223ZMutex::ZMutex(bool fgd)
224{
225 _mutx = new pthread_mutex_t;
226 _condv = new pthread_cond_t;
227 int rc;
228 rc = pthread_mutex_init(_mutx, NULL);
229 CheckSt(rc,"ZMutex::ZMutex() Pb pthread_mutex_init");
230 rc = pthread_cond_init(_condv, NULL);
231 CheckSt(rc,"ZMutex::ZMutex() Pb pthread_cond_init");
232 _fgd = fgd;
233}
234
235ZMutex::~ZMutex()
236{
237 if (_fgd == false) return;
238 int rc;
239 rc = pthread_mutex_destroy(_mutx);
240 CheckSt(rc,"ZMutex::~ZMutex() Pb pthread_mutex_destroy");
241 rc = pthread_cond_destroy(_condv);
242 CheckSt(rc,"ZMutex::~ZMutex() Pb pthread_cond_destroy");
243 delete _mutx;
244 delete _condv;
245}
246
247/*!
248 \class SOPHYA::ZSync
249 \ingroup SysTools
250 \brief Wrapper/utility class ensuring synchronised execution of an instruction bloc.
251
252 This class can be used to insure that the execution of a given
253 part of the code is synchronised, i.e. only a single thread
254 goes through this at a given time.
255 The constructor acquires a lock on given \b ZMutex object,
256 which is released by the destructor.
257 The ZSync object should then be instanciated at the beginning of
258 the synchronised instruction bloc.
259 \sa SOPHYA::ZMutex
260*/
Note: See TracBrowser for help on using the repository browser.