⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 thread.h

📁 用c++包装好的线程库,直接拿来使用,提高效率.
💻 H
📖 第 1 页 / 共 2 页
字号:
/*************************************************************************** *                                                                         * *   This program is free software; you can redistribute it and/or modify  * *   it under the terms of the GNU General Public License as published by  * *   the Free Software Foundation; either version 2 of the License, or     * *   (at your option) any later version.                                   *  *                                                                         * ***************************************************************************//** * Copyright (c) 1999 * * A C++ implementation of posix threads, using Linux clone system * calls. * * This implementation provides threads, similar to the linuxthreads * package, except where each thread is a class here. * * @author Orn Hansen <oe.hansen@gamma.telenordia.se> * @short a C++ implementation of threads for linux. */#ifndef __THREADS_LIBRARY_H#define __THREADS_LIBRARY_H/** * This definition makes all classes loaded after it, to be thread * safe.  Mainly, this is for the standard template library, which  * will include some mutexes to ensure safety in allocation  * classes. * * Make sure to load this file first, in your program. */#define _THREAD_SAFE#define DEFAULTMUTEX        mutex_t()namespace cpp_threads {class Mutex;class Cond;class spinlock;};//// These definitions are required by the standard template library,// and we use a spinlock variable, to avoid inner conflict.//typedef cpp_threads::spinlock    mutex_t;#define mutex_lock(x)       ((mutex_t *)x)->acquire()#define mutex_unlock(x)     ((mutex_t *)x)->release()#include <threads/stl.h>#include <threads/mutex.h>#include <threads/cond.h>#include <threads/semaphore.h>extern "C" {#  include <setjmp.h>#  include <unistd.h>};#define CPPTHREAD_CANCELED           (-1)#define CPPTHREAD_SIG_RESTART        s_continue#define CPPTHREAD_SIG_CANCEL         s_quitnamespace cpp_threads {  class ThreadStack;  /**   * Threads, are cloned processes that share the same   * memory for reading and writing.  This is a primitive   * and needs to be a superclass to any specific needs for   * threaded execution.   *   * @short Abstract class for threads.   * @author Orn Hansen <oe.hansen@gamma.telenordia.se>   */  class Pthread {  public:    enum cancel_state {      cancel_enable_e,      cancel_disable_e    };    enum cancel_type {      cancel_deferred_e,      cancel_asynchronous_e    };    enum jumps {      signal_jmp_e,      cancel_jmp_e    };    enum thread_state {      p_running_e,      p_stopped_e,      p_suspended_e,      p_canceled_e,      p_terminated_e,      p_exited_e,      p_jointhread_e    };    enum booleans {      set_terminated_e,      set_detached_e,      set_exited_e,      set_canceled_e,      set_private_e    };      private:    Semaphore*      _runner;    pid_t           _tid;    pid_t           _ppid;    ThreadStack*    _sp;    spinlock        _spinlock;    attributes      _attributes;    int             _priority;    int             _signal;    int             _joining;    int             _errno;    void*           _retval;    int             _retcode;    sigjmp_buf*     _signal_jmp;    sigjmp_buf*     _cancel_jmp;    sigjmp_buf*     _polled_jmp;    thread_state    _state;    cancel_state    _cancelstate;    cancel_type     _canceltype;        void varinit();    void invoke(void *,Semaphore *,size_t);    static int __routine(void *);  protected:    /**     * These are routines that handle signals within the     * threads.     *     * Initialize all signal handlers, on a thread start     * ensuring terminating signals will get cought and     * terminate the program properly.     */    static void signal_init();    /** Suspend the thread, from an outside thread */    static void sig_stop(int);    /** Cancel the thread */    static void sig_cancel(int);    /** Generic handler */    static void sig_handler(int);    /** Child exit, to remove children from zombie status.  */    static void sig_childexit(int);    /** Terminate the process, ensure program termination proper */    static void sig_terminate(int);  protected:    bool error(int val)               { _errno = val; return false; };        /**     * Cleanup()     *     * This will browse the list of threads, for any possible child     * threads, and terminate these if possible.     */    static void cleanup();    /**     * exit_child()     *     * Does what is needed, when a child exits.     */    static void exit_child(int);  public:    /**     * Create a thread, without any starting arguments.     *     * When a thread is created, some compilers will not have     * the virtual tables filled in at that time.  It is also     * to notice, that without control, the thread will start     * before the constructor has finished creating the environment     * the thread is to run in.  By providing a semaphore as a     * parameter, the thread will actually wait for a post on it     * before activating the class thread.  Giving the compiler     * and user functions time to initalize before the thread     * starts using variables in the class.     *     * <pre>     * example:     *     * Semaphore sem;     * Pthread *p = new mythread(&sem);     * sem.post(); // or p->run();     * </pre>     *     * As of version 3.0, the above functionality is provided     * by default.  So, in version 3.0 and above, to actually     * make the thread start, the following must be done...     *     * <pre>     * example:     *     * Pthread *p = new mythread();     * p->run();     * </pre>     *     * @param sem A semaphore to control the thread initialisation.     * @param pages Number of stack pages to allocate for the thread.     */    Pthread(Semaphore* sem=0,size_t pages=0);    /**     * Create a thread, with starting arguements.  This is equivalent     * to the above routine, except for the arguement that is     * provided.     *     * @param arg The arguement to send to the thread.     * @param sem A semaphore to control the thread initialisation.     * @param pages Number of stack pages to allocate for the thread.     */    Pthread(void *,Semaphore* sem=0,size_t pages=0);    /**     * This is a convenience function, to create a controlling     * environment around an existing routine.     *     * @param id The process id, of a running process.     */    Pthread(int);    virtual ~Pthread();    thread_state state();    thread_state state(thread_state);        /**     * An abstract definition of the method, that will be run     * as a different process by this class.  This is the starting     * point, of the new process.     *     * In creating a new process, it should be taken care off that     * the process itself, is starting its execution at the same     * time as the construction is initializing class variables.  This     * may be unwanted, and to have a process wait for the initialization     * to finish, the following method can be used.  And is provided     * by default, by an internal semaphore.     *     * <pre>     *     * #include <thread.h>     *     * class mythread : public Pthread {     * private:     *   Semaphore run_away;     *   string something;     *     * public:     *   mythread()     *   {     *     something = "This has been initialized";     *     run_away.post();   // last instruction in constructor.     *   }     *   ~mythread()     *   {     *      // TODO: destroy variables.     *   }     *     *   int thread(void *)     *   {     *      run_away.wait();     *      // Now, the process is synchronized to run after     *      // the initialisation has finished.     *   }     * };     *     * </pre>     *     * The above mechanism, can both be seen as a quirk, and as a drawback.     * In most cases, the thread doesn't need the variables in its class,     * so forcing the thread to wait until the constructor has finished     * isn't necessary... and perhaps even unwanted.     *     * @param any The process will receive a parameter, whose type is only known internally.     * @return Actually, nothing is returned here.  See @ref #retval how to acquire return values.     */    virtual int thread(void *)       = 0;        /**     * If the class is initialized with a hold off semaphore, to allow     * the constructor to conclude its job, then post to the semaphore     * here, to cause the thread to run.     */    void run();    /**     * This method allows access to the value returned by the process, if     * it has returned, that is.  Otherwise, it contains an undefined value.     *     * @return A pointer, that the thread can register as a return value.     */    void *retval() const              { return _retval; };    /**     * This method defines, wether the thread is joining with another     * thread.  The return value, is either the process id of the     * thread that is to be joined with, or 0 which indicates that     * it is not being joined with anyone.     *     * @return the pid of the process to join with.     */    int  joining() const              { return _joining; };    /**     * If an error has occurred, during the process, it will be locally     * stored and can be retrieved by this method.  Note however, that     * it is upon the user to make sure that his thread sets this value     * with the @ref #error function.     *     * @return The last errorvalue registered.     */    int  gerrno() const               { return _errno; };    /**     * Each thread has its own process id, and even though it is     * possible with the clone system to clone the process id as well,     * it is not done within this thread package.     *     * @return the pid of this thread.     */    int  id() const                   { return _tid; };    /**     * Each thread has a parent process, and this is the stored     * number of it.  It is to simplify the manner in which     * programs can achieve it, as they don't have to call     * expansive kernel routines.     */     int ppid() const                 { return _ppid; };    /**      * Each time a thread receives a signal, it stores the     * signal number locally so that parent threads can view     * or debug its status.     *     * @return Last signal received by the thread.     */    int  signal() const               { return _signal; };    /**     * This is a convenience function, provided to simplify the     * use of sending signals to a thread.  If the user has access to     * the thread class, he can use this method to signal the thread     * instead of the system kill function.     *     * @return Last signal received by the thread.     */    int  signal(int);        /**     * A running thread can terminate in several ways, it can     * terminate by returning or exiting from the thread, or it     * can be canceled from inside or from an outside source.     * This function reports if the thread was canceled.     *     * @return True if the thread has been canceled.     */    bool canceled() const;    /**     * Usually all threads created by the main program will be     * hanging on to it.  This means, that when the main program     * stops execution, the thread belonging to it will be     * terminated when it exits.  The thread can however detach     * itself from the main thread.     *     * @return True if the thread has been detached.     */    bool detached() const;    /**     * A detached thread, isn't joinable... there may also be     * other situations where a thread does not want a parent     * thread to join onto it.     *

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -