//Thread.hpp
#pragma once
#include <iostream>
#include <string>
#include <functional>
#include <pthread.h>
namespace ThreadModule
{
static int gnumber = 1;
template <typename T>
using callback_t = std::function<void(T &)>;
enum class TSTATUS
{
THREAD_NEW,
THREAD_RUNNING,
THREAD_STOP
};
std::string Status2String(TSTATUS s)
{
switch (s)
{
case TSTATUS::THREAD_NEW:
return "THREAD_NEW";
case TSTATUS::THREAD_RUNNING:
return "THREAD_RUNNING";
case TSTATUS::THREAD_STOP:
return "THREAD_STOP";
default:
return "UNKNOWN";
}
}
std::string IsJoined(bool joinable)
{
return joinable ? "true" : "false";
}
template <typename T>
class Thread
{
private:
void ToRunning()
{
_status = TSTATUS::THREAD_RUNNING;
}
void ToStop()
{
_status = TSTATUS::THREAD_STOP;
}
static void *ThreadRoutine(void *args)
{
Thread *self = static_cast<Thread<T> *>(args);
pthread_setname_np(self->_tid, self->_name.c_str());
self->_cb(self->_date);
self->ToStop();
return nullptr;
}
public:
Thread(callback_t<T> cb, const T &date):
_tid(-1),
_status(TSTATUS::THREAD_NEW),
_joinable(true),
_cb(cb),
_result(nullptr),
_date(date)
{
_name = "New-Thread-" + std::to_string(gnumber++);
}
bool Start()
{
int n = pthread_create(&_tid, nullptr, ThreadRoutine, this);
if (n != 0)
return false;
ToRunning();
return true;
}
void Join()
{
if (_joinable)
{
int n = pthread_join(_tid, &_result);
if (n != 0)
{
std::cerr << "join error: " << n << std::endl;
return;
}
(void)_result;
_status = TSTATUS::THREAD_STOP;
}
else
{
std::cerr << "error, thread join status: " << IsJoined(_joinable) << std::endl;
}
}
// void Stop() // restart()
// {
//
// }
void Die()
{
if (_status == TSTATUS::THREAD_RUNNING)
{
pthread_cancel(_tid);
_status = TSTATUS::THREAD_STOP;
}
}
void Detach()
{
if (_status == TSTATUS::THREAD_RUNNING && _joinable)
{
pthread_detach(_tid);
_joinable = false;
}
else
{
std::cerr << "detach " << _name << " failed" << std::endl;
}
}
void PrintInfo()
{
std::cout << "thread name : " << _name << std::endl;
std::cout << "thread _tid : " << _tid << std::endl;
std::cout << "thread _status : " << Status2String(_status) << std::endl;
std::cout << "thread _joinable : " << IsJoined(_joinable) << std::endl;
}
~Thread()
{
}
private:
std::string _name;
pthread_t _tid;
TSTATUS _status;
bool _joinable;
callback_t<T> _cb;
T _date;
// 线程退出信息
void *_result;
};
}
//Main.cc
#include "Thread.hpp"
#include <unistd.h>
#include <vector>
class ThreadDate
{
public:
ThreadDate(int x , int y):_x(x) , _y(y)
{}
public:
int _x;
int _y;
int _result;
};
void Loop(ThreadDate &td)
{
char name[64];
pthread_getname_np(pthread_self(), name, sizeof(name));
std::cout<<td._x <<" , " <<td._y <<std::endl;
sleep(1);
// while(cnt)
// {
// std::cout << "new thread running: " << name << " cnt : " << cnt-- << std::endl;
// sleep(1);
// }
}
int main()
{
ThreadDate td(10,20);
std::vector<ThreadModule::Thread<ThreadDate>> threads;
const int num = 10;
for(int i = 0; i < 10; i++)
{
threads.emplace_back(Loop , td);
}
for(auto &t : threads)
{
t.Start();
//sleep(1);
}
// sleep(10);
// for(auto &t : threads)
// {
// t.Die();
// }
for(auto &t : threads)
{
t.Join();
t.PrintInfo();
// sleep(1);
}
// std::queue<Thread> threads;
// while(true)
// {
// // t = threads.pop();
// t.restart();
// sleep(1);
// t.stop();
// threads.push(t);
// }
// ThreadModule::Thread t(Loop, a, name, xxxx);
// sleep(1);
// t.Start();
// t.Detach();
// sleep(5);
// t.Die();
// sleep(1);
// t.Join();
// t.PrintInfo();
return 0;
}
#makefile
thread:Main.cc
g++ -o $@ $^ -std=c++11
.PHONY:clean
clean:
rm -f thread
