1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141
|
#include <stdio.h>
#include <iostream>
using namespace std;
#include <unistd.h>
#include <pthread.h>
class JobBase
{
public:
bool start()
{
return createAndRun();
}
virtual ~JobBase();
protected:
JobBase(void* _jobParam,bool _joinable=false)
: jobStatus(Job_Unkown), thread(0),
jobParam(_jobParam),joinable(_joinable)
{}
protected:
/**
* @jobThread
* the faked thread entry to do special work
* @param: void* param, user defined thread parameter
* @return: void* as thread callback function
*/
static void* jobThread(void* param);
/**
* @jobEntry
* the real entry to do special work
* @param: void
* @return: void* as thread callback function
*/
virtual void* jobEntry() = 0; /*here, it would make the program terminated in runtime,system error: pure virtual method called
terminate called without an active exception
*/
virtual void onJobCompleted(void* jobRet);
/**
* @createAndRun
* create and start internal thread
* @params: void
* @return: true for success
*/
bool createAndRun();
protected:
typedef enum{
Job_Unkown = 0,
Job_Ready, //ready to be started
Job_Stopped, //not running
Job_Running, //is busy
Job_BeingExit //being exit, should do any further work
}JobStatus;
JobStatus jobStatus; //indicate the internal thread status
private:
pthread_t thread;
bool joinable;
void* jobParam;
};
bool JobBase::createAndRun()
{
bool bRet = false;
if(jobStatus==Job_Unkown){
pthread_attr_t attr;
pthread_attr_init(&attr);
if(!pthread_attr_setdetachstate(&attr,joinable?PTHREAD_CREATE_JOINABLE:PTHREAD_CREATE_DETACHED)){
if(!pthread_create(&thread,&attr,jobThread,jobParam)){
bRet = true;
jobStatus = Job_Running;
}
}
pthread_attr_destroy(&attr);
}
return bRet;
}
/*
void* JobBase::jobEntry()
{
cout<<"Stange"<<endl;
return NULL;
}
*/
void* JobBase::jobThread(void* param)
{
JobBase* pThis = (JobBase*)param;
if(pThis)
pThis->onJobCompleted(pThis->jobEntry());
return NULL;
}
void JobBase::onJobCompleted(void* jobRet)
{
cout<<"Job completed!"<<endl;
jobStatus = Job_Stopped;
}
JobBase::~JobBase()
{
if(jobStatus!=Job_Unkown && jobStatus==Job_Running){
if(joinable){
void* pret = NULL;
pthread_join(thread,&pret);
}else{
cout<<"Job was uncompleted, its unsafe!"<<endl;
}
}
}
class TestJob : public JobBase
{
public:
TestJob():JobBase(this,true){}
protected:
virtual void* jobEntry()
{
int i = 100;
while(i>0){
cout<<i<<endl;
--i;
fflush(stdout);
}
return NULL;
}
};
int main(int argc,char* argv[])
{
cout<<"Hello world!"<<endl;
TestJob job;
job.start();
fflush(stdout);
return 0;
}
|