📄 ofthread.h
字号:
/* * * Copyright (C) 1997-2005, OFFIS * * This software and supporting documentation were developed by * * Kuratorium OFFIS e.V. * Healthcare Information and Communication Systems * Escherweg 2 * D-26121 Oldenburg, Germany * * THIS SOFTWARE IS MADE AVAILABLE, AS IS, AND OFFIS MAKES NO WARRANTY * REGARDING THE SOFTWARE, ITS PERFORMANCE, ITS MERCHANTABILITY OR * FITNESS FOR ANY PARTICULAR USE, FREEDOM FROM ANY COMPUTER DISEASES OR * ITS CONFORMITY TO ANY SPECIFICATION. THE ENTIRE RISK AS TO QUALITY AND * PERFORMANCE OF THE SOFTWARE IS WITH THE USER. * * Module: ofstd * * Author: Marco Eichelberg * * Purpose: Provides operating system independent abstractions for basic * multi-thread concepts: threads, thread specific data, * semaphores, mutexes and read/write locks. The implementation * of these classes supports the Solaris, POSIX and Win32 * multi-thread APIs. * * Last Update: $Author: meichel $ * Update Date: $Date: 2005/12/08 16:06:08 $ * CVS/RCS Revision: $Revision: 1.9 $ * Status: $State: Exp $ * * CVS/RCS Log at end of file * */#ifndef OFTHREAD_H#define OFTHREAD_H#include "dcmtk/config/osconfig.h"#include "dcmtk/ofstd/oftypes.h" /* for class OFBool */#include "dcmtk/ofstd/ofstring.h" /* for class OFString *//** Stub function with extern "C" linkage that is passed as a function pointer * to the system function that creates the thread. * @param arg pointer to the OFThread instance to be started, passed as void pointer. */extern "C"{#ifdef HAVE_WINDOWS_H unsigned int __stdcall thread_stub(void *arg);#else void *thread_stub(void *arg);#endif}/** provides an operating system independent abstraction for threads. * Threads are executed asynchronously in parallel to the main thread * of the process. On multi-processor machines threads may run on * different CPUs if the operating system permits. * This class is abstract. Deriving classes must implement the run() * method which contains the code executed by the thread. */class OFThread{public: /** default constructor. The new thread is not started immediately * upon creation of the OFThread object. Calling the start() * method causes the creation of the thread. */ OFThread(); /** destructor. Destruction of an OFThread object does not cause * the referenced thread to be stopped and may result in undefined * behaviour if the derived class maintains thread specific data * in this object (which is not recommended). * The join() method should be called prior to destruction * of the thread object to make sure a thread has terminated. */ virtual ~OFThread(); /** adds a new thread of control to the current process. The main() * procedure itself is a single thread of control. Each thread executes * simultaneously with all the other threads within the calling * process. A newly created thread shares all of the calling process' * global data with the other threads in this process except the * execution stack. The new thread executes the run() method and * terminates upon return from this method or a call to thread_exit() * from within the thread. This method should not be called if a thread * is already running, otherwise a new thread will be started and the * identifier of the old thread will be overwritten, making it * impossible to call join() for the old thread. It may also result in * undefined behaviour if the derived class maintains thread specific * data in this object (which is not recommended). * @return 0 upon success, an error code otherwise. */ int start(); /** blocks the calling thread until the thread referenced by the OFThread * object terminates. Several threads cannot wait for the same thread to * complete; one thread will complete the join() method successfully * others may or may not return OFThread::busy. The method will not * block the calling thread if the target thread has already terminated. * @return 0 upon success, OFThread::busy if another thread is already * waiting for the termination of the target thread, * an error code otherwise. */ int join(); /** returns the thread identifier of the thread referenced by the * OFThread object, if the thread has already been started. * Otherwise returns 0. On certain platforms like OSF/1, a thread ID * contains a pointer to a structure. Therefore, thread IDs should * never be compared directly, but always using the equal() method * provided in this class. * @return thread ID of target thread if started, 0 otherwise. */ unsigned long threadID(); /** checks if the given thread ID matches the thread ID of the thread * referenced by this object. * @param tID thread ID to be compared * @return OFTrue if equal, OFFalse otherwise. */ OFBool equal(unsigned long tID); /** converts any of the error codes returned by the methods of this class * into a textual description, which is written into the string object. * @param description string object into which the error description is written. * @param code error code */ static void errorstr(OFString& description, int code); /** this constant is returned by the join() method if another thread * is already waiting for termination of the thread referenced by the * OFThread object. Since this value is operating system dependent, * comparisons should always compare the return value of join() * with this constant. */ static const int busy;protected: /** terminates the calling thread, in a similar way that exit() * terminates the calling process. This method does not return. */ static void thread_exit(); /** returns the thread ID of the calling thread. For a running thread, * this->threadID() and this->self() should return the same value, * but self() is more robust and should be preferred. * On certain platforms like OSF/1, a thread ID * contains a pointer to a structure. Therefore, thread IDs should * never be compared directly, but always using the equal() method * provided in this class. * @return thread ID of the calling thread. */ static unsigned long self();private: /** this method implements the thread that is run by calling the start * method of the OFThread object. Defined as abstract method in OFThread. * It is recommended that derived classes implementing this method * do not rely on attributes of the OFThread object because this might * result in undefined behaviour if another thread deletes or restarts the * OFThread object before the thread has terminated. */ virtual void run() = 0;#ifdef HAVE_WINDOWS_H /** thread handle (Win32 only) */ unsigned long theThreadHandle;#endif /** thread identifier */#ifdef HAVE_POINTER_TYPE_PTHREAD_T void *theThread;#else unsigned long theThread;#endif /** unimplemented private copy constructor */ OFThread(const OFThread& arg); /** unimplemented private assignment operator */ OFThread& operator=(const OFThread& arg); /** thread stub must be friend to call run() */#ifdef HAVE_WINDOWS_H friend unsigned int __stdcall thread_stub(void *arg);#else friend void *thread_stub(void *arg);#endif};/** provides an operating system independent abstraction for thread * specific data. An instance of this class manages a key which is global * to all threads in the process but locates data specific to each thread. * Each thread can set a different value once the object has been created. * Upon creation, the value NULL is assigned for all threads. This class * does not perform any memory management on the objects pointed to. * Threads must ensure on their own that the data pointed to by the thread * specific data key is freed upon termination of the thread. */class OFThreadSpecificData{public: /** default constructor */ OFThreadSpecificData(); /** destructor. Deletes all thread specific key values (pointers), but * not the objects pointed to. */ ~OFThreadSpecificData(); /** checks whether creation of the object was successful. * @return OFTrue if the object was successfully created, OFFalse otherwise. */ OFBool initialized() const; /** sets the thread specific value for this object. No attempt is made to * automatically delete the object pointed to at the termination of the * thread. * @param value new pointer to thread-specific data for this object. * @return 0 if successful, an error code otherwise. */ int set(void *value); /** retrieves the thread specific value for this object. If no call to set() * has been made for the calling thread before, NULL is returned. * @param value new pointer to thread-specific data for this object * returned in this parameter. * @return 0 if successful, an error code otherwise. */ int get(void *&value); /** converts any of the error codes returned by the methods of this class * into a textual description, which is written into the string object. * @param description string object into which the error description is written. * @param code error code */ static void errorstr(OFString& description, int code);private: /** thread specific data key resource */#ifdef HAVE_CXX_VOLATILE volatile#endif void *theKey; /** unimplemented private copy constructor */ OFThreadSpecificData(const OFThreadSpecificData& arg); /** unimplemented private assignment operator */ OFThreadSpecificData& operator=(const OFThreadSpecificData& arg);};/** provides an operating system independent abstraction for semaphores. * A semaphore is a non-negative integer counter that is used * to coordinate access to resources. The initial and maximum value of the counter * is defined by the constructor. Each call to wait() decreases * the counter by one and each call to post() increases the count by one. * If a thread calls wait() while the counter is zero, the thread * is blocked until another thread has increased the counter using post().
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -