📄 thread.h
字号:
/*************************************************************************** * * * 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. * * The implementation is identical to the implementation found in * the linuxthreads package, except that each thread is an object * here. * * Using Linux pthread package, has a rather bad * bi-effect in C++. When a routine, is called * inside a class, it looses it's scope on the * class. That is, the 'this' pointer. This * superclass is to remedy that. * * @author Orn Hansen <oe.hansen@gamma.telenordia.se> * @short a C++ implementation of threads for linux. */#ifndef __THREADS_LIBRARY_H#define __THREADS_LIBRARY_H#define _THREAD_SAFE#define DEFAULTMUTEX mutex_t()class mutex;class cond;class spinlock;typedef mutex mutex_t;typedef cond cond_t;typedef spinlock spinlock_t;#define mutex_lock(x) ((mutex_t *)x)->lock()#define mutex_unlock(x) ((mutex_t *)x)->unlock()#include <thread_alloc.h>#include <thread_mutex.h>#include <thread_cond.h>#include <thread_semaphore.h>extern "C" {# include <setjmp.h># include <unistd.h>};#ifndef PTHREAD_CANCELED#define PTHREAD_CANCELED ((void *)-1)#endif#define PTHREAD_SIG_RESTART s_user1#define PTHREAD_SIG_CANCEL s_user2/** * 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, cancel_disable }; enum cancel_type { cancel_deferred, cancel_asynchronous }; enum jumps { signal_jmp, cancel_jmp }; enum booleans { set_terminated, set_detached, set_exited, set_canceled, set_private }; private: int p_id; char* p_sp; spinlock p_spinlock; attributes p_attributes; int p_priority; int p_signal; int p_joining; int p_errno; void* p_retval; int p_retcode; sigjmp_buf* p_signal_jmp; sigjmp_buf* p_cancel_jmp; bool p_terminated; bool p_exited; cancel_state p_cancelstate; cancel_type p_canceltype; bool p_canceled; void varinit(); void invoke(void *); bool error(int val) { p_errno = val; return false; }; public: pthread(); pthread(void *); pthread(int); virtual ~pthread(); /** * 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. * * <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; /** * 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 p_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 p_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 p_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 p_id; }; /** * 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 p_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 { return p_canceled; }; /** * 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. * * @return True if the thread can be joined with. */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -