commit
7cdca9d255
@ -0,0 +1,22 @@
|
|||||||
|
|
||||||
|
#ifndef CPP_START_NON_COPY_ABLE_H
|
||||||
|
#define CPP_START_NON_COPY_ABLE_H
|
||||||
|
|
||||||
|
|
||||||
|
class NonCopyAble {
|
||||||
|
|
||||||
|
protected:
|
||||||
|
NonCopyAble() = default;
|
||||||
|
|
||||||
|
~NonCopyAble() = default;
|
||||||
|
|
||||||
|
public:
|
||||||
|
// 禁用复制构造
|
||||||
|
NonCopyAble(const NonCopyAble &) = delete;
|
||||||
|
|
||||||
|
// 禁用赋值构造
|
||||||
|
NonCopyAble &operator=(const NonCopyAble &) = delete;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
#endif //CPP_START_NON_COPY_ABLE_H
|
@ -0,0 +1,292 @@
|
|||||||
|
#include <iostream>
|
||||||
|
#include <map>
|
||||||
|
#include <thread>
|
||||||
|
|
||||||
|
template<typename T>
|
||||||
|
class iterator {
|
||||||
|
public:
|
||||||
|
using value_type = T;
|
||||||
|
using size_type = size_t;
|
||||||
|
|
||||||
|
private:
|
||||||
|
size_type cursor_;
|
||||||
|
const value_type step_;
|
||||||
|
value_type value_;
|
||||||
|
|
||||||
|
public:
|
||||||
|
|
||||||
|
iterator(size_type cur_satrt, value_type begin_val, value_type step_val)
|
||||||
|
:
|
||||||
|
cursor_(cur_satrt),
|
||||||
|
step_(step_val),
|
||||||
|
value_(begin_val) {
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
value_type operator*() const {
|
||||||
|
return value_;
|
||||||
|
};
|
||||||
|
|
||||||
|
bool operator!=(const iterator &rhs) const {
|
||||||
|
return (cursor_ != rhs.cursor_);
|
||||||
|
};
|
||||||
|
|
||||||
|
iterator *operator++() {
|
||||||
|
value_ += step_;
|
||||||
|
++cursor_;
|
||||||
|
return (*this);
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
void foreach() {
|
||||||
|
std::map<std::string, int> mm = {
|
||||||
|
{"a", 1},
|
||||||
|
{"b", 2},
|
||||||
|
{"c", 3}
|
||||||
|
};
|
||||||
|
|
||||||
|
for (const auto &m: mm) {
|
||||||
|
std::cout << m.first << " -> " << m.second << std::endl;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
int g_constructCount = 0;
|
||||||
|
int g_copy_constructCount = 0;
|
||||||
|
int g_destructCount = 0;
|
||||||
|
|
||||||
|
class A {
|
||||||
|
|
||||||
|
public:
|
||||||
|
A() {
|
||||||
|
std::cout << "construct: " << ++g_constructCount << std::endl;
|
||||||
|
}
|
||||||
|
|
||||||
|
A(const A &a) {
|
||||||
|
std::cout << "copy construct: " << ++g_copy_constructCount << std::endl;
|
||||||
|
}
|
||||||
|
|
||||||
|
~A() {
|
||||||
|
std::cout << "destruct: " << ++g_destructCount << std::endl;
|
||||||
|
}
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
A getA() {
|
||||||
|
return A{};
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
template<typename T>
|
||||||
|
struct GetLeftSize : std::integral_constant<int, 10> {
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
template<typename ... T>
|
||||||
|
void f(T ... args) {
|
||||||
|
std::cout << sizeof...(args) << std::endl;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
template<typename ... T>
|
||||||
|
void expand(T ... args) {
|
||||||
|
std::initializer_list<int>{(std::cout << args << std::endl, 0)...};
|
||||||
|
}
|
||||||
|
|
||||||
|
template<typename F, typename Arg>
|
||||||
|
auto Func(F f, Arg arg) -> decltype(f(arg)) {
|
||||||
|
return f(arg);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
template<typename Fn, typename Arg>
|
||||||
|
auto GroupBy(const std::vector<Arg> &vt, Fn &&keySelector)
|
||||||
|
-> std::multimap<decltype(keySelector((Arg & )
|
||||||
|
|
||||||
|
nullptr)), Arg>
|
||||||
|
{
|
||||||
|
typedef decltype(keySelector(*(Arg * ) nullptr))
|
||||||
|
key_type;
|
||||||
|
std::multimap<key_type, Arg> map;
|
||||||
|
std::for_each(vt
|
||||||
|
.
|
||||||
|
|
||||||
|
begin(), vt
|
||||||
|
|
||||||
|
.
|
||||||
|
|
||||||
|
end(),
|
||||||
|
|
||||||
|
[&](
|
||||||
|
const Arg &arg
|
||||||
|
){
|
||||||
|
map.
|
||||||
|
insert(make_pair(keySelector(arg), arg)
|
||||||
|
);
|
||||||
|
});
|
||||||
|
return
|
||||||
|
map;
|
||||||
|
}
|
||||||
|
|
||||||
|
std::mutex g_lock;
|
||||||
|
|
||||||
|
void func() {
|
||||||
|
std::lock_guard<std::mutex> locker(g_lock);
|
||||||
|
std::this_thread::sleep_for(std::chrono::seconds(2));
|
||||||
|
}
|
||||||
|
|
||||||
|
#include "sync_queue.h"
|
||||||
|
void sync_test(){
|
||||||
|
// 同步队列
|
||||||
|
auto queue = new SyncQueue<int>(3);
|
||||||
|
|
||||||
|
// 每2秒取出进行消费
|
||||||
|
std::thread producer([&](){
|
||||||
|
int i = 0;
|
||||||
|
while (i < 9){
|
||||||
|
queue->dequeue(i);
|
||||||
|
std::this_thread::sleep_for(std::chrono::seconds(2));
|
||||||
|
std::cout << "dequeue: " << i << std::endl;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
// 持续写入
|
||||||
|
std::thread consumer([&](){
|
||||||
|
for (int i = 0; i < 10; ++i) {
|
||||||
|
queue->enqueue(i);
|
||||||
|
std::cout << "enqueue: " << i << std::endl;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
producer.join();
|
||||||
|
consumer.join();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
#include <chrono>
|
||||||
|
#include <iomanip>
|
||||||
|
#include "stop_watch.h"
|
||||||
|
|
||||||
|
void chrono_test(){
|
||||||
|
|
||||||
|
StopWatch stopWatch;
|
||||||
|
|
||||||
|
std::chrono::minutes t1(10);
|
||||||
|
std::chrono::seconds t2(60);
|
||||||
|
std::chrono::seconds t3 = t1 - t2;
|
||||||
|
std::cout << "duration time: " << t3.count() << std::endl;
|
||||||
|
|
||||||
|
std::cout << "\ncost time: " << stopWatch.elapsed<std::chrono::microseconds>() << " us\n" << std::endl;
|
||||||
|
|
||||||
|
std::chrono::system_clock::time_point now = std::chrono::system_clock::now();
|
||||||
|
// 将 time_point 转为 ctime
|
||||||
|
std::time_t last = std::chrono::system_clock::to_time_t(now - std::chrono::hours(24));
|
||||||
|
std::time_t next = std::chrono::system_clock::to_time_t(now + std::chrono::hours (24));
|
||||||
|
|
||||||
|
// 使用put_time格式化时间
|
||||||
|
std::cout
|
||||||
|
<< "One day ago, the time was "
|
||||||
|
<< std::put_time(std::localtime(&last), "%F %T")
|
||||||
|
<< "\n"
|
||||||
|
<< "NExt day ago, the time is "
|
||||||
|
<< std::put_time(std::localtime(&next), "%F %T")
|
||||||
|
|
||||||
|
<< std::endl;
|
||||||
|
|
||||||
|
std::cout << "\ncost time: " << stopWatch.elapsed() << " ms\n" << std::endl;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
#include "thread_pool.h"
|
||||||
|
void thread_test(){
|
||||||
|
ThreadPool pool(3,10);
|
||||||
|
|
||||||
|
std::thread t0([&pool]{
|
||||||
|
for (int i = 0; i < 100; ++i) {
|
||||||
|
auto thdId = std::this_thread::get_id();
|
||||||
|
pool.add([thdId]{
|
||||||
|
std::cout << "thread 1 id:" << thdId << std::endl;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
std::thread t1([&pool]{
|
||||||
|
for (int i = 0; i < 100; ++i) {
|
||||||
|
auto thdId = std::this_thread::get_id();
|
||||||
|
pool.add([thdId]{
|
||||||
|
std::cout << "thread 2 id:" << thdId << std::endl;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
std::this_thread::sleep_for(std::chrono::seconds(2));
|
||||||
|
// getchar();
|
||||||
|
|
||||||
|
pool.stop();
|
||||||
|
t0.join();
|
||||||
|
t1.join();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
#include "aspect/aspect.h"
|
||||||
|
#include "test/time_elapsed_aspect.h"
|
||||||
|
#include "test/log_aspect.h"
|
||||||
|
void HT(int a)
|
||||||
|
{
|
||||||
|
std::cout << "real HT function " << a << std::endl;
|
||||||
|
}
|
||||||
|
void aop_test(){
|
||||||
|
using namespace std;
|
||||||
|
|
||||||
|
aop<LogAspect, TimeElapsedAspect>([](int a){
|
||||||
|
std::thread t([a](){
|
||||||
|
std::this_thread::sleep_for(std::chrono::seconds(1));
|
||||||
|
std::cout << "run function, arg is " << a << std::endl;
|
||||||
|
});
|
||||||
|
t.join();
|
||||||
|
}, 1);
|
||||||
|
|
||||||
|
cout << endl;
|
||||||
|
|
||||||
|
std::function<void(int)> f = std::bind(&HT, std::placeholders::_1);
|
||||||
|
aop<LogAspect>(f, 100);
|
||||||
|
}
|
||||||
|
|
||||||
|
int main() {
|
||||||
|
// 同步队列测试
|
||||||
|
// sync_test();
|
||||||
|
// 时间工具测试
|
||||||
|
// chrono_test();
|
||||||
|
// 线程池测试
|
||||||
|
// thread_test();
|
||||||
|
// AOP测试
|
||||||
|
aop_test();
|
||||||
|
|
||||||
|
|
||||||
|
// auto start = std::chrono::duration_cast<std::chrono::milliseconds>(
|
||||||
|
// std::chrono::system_clock::now().time_since_epoch()).count();
|
||||||
|
// std::cout << "start time: " << start / 1000 << std::endl;
|
||||||
|
// std::thread t0(func);
|
||||||
|
// std::thread t1(func);
|
||||||
|
// std::thread t2(func);
|
||||||
|
// t0.join(); // 阻塞执行
|
||||||
|
// t1.detach(); // 分离线程何对象,之后就无法何线程发送联系
|
||||||
|
// t2.join();
|
||||||
|
// auto end = std::chrono::duration_cast<std::chrono::milliseconds>(
|
||||||
|
// std::chrono::system_clock::now().time_since_epoch()).count();
|
||||||
|
// std::cout << " end time: " << end / 1000 << std::endl;
|
||||||
|
|
||||||
|
// A&& a = getA();
|
||||||
|
//
|
||||||
|
// expand(1,2,3,4);
|
||||||
|
//
|
||||||
|
// std::cout << GetLeftSize<int>::value << std::endl;
|
||||||
|
//
|
||||||
|
// f();
|
||||||
|
// f(1);
|
||||||
|
// f(1,2.5,"");
|
||||||
|
//
|
||||||
|
// foreach();
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
@ -0,0 +1,32 @@
|
|||||||
|
|
||||||
|
#ifndef CPP_START_STOP_WATCH_H
|
||||||
|
#define CPP_START_STOP_WATCH_H
|
||||||
|
|
||||||
|
#include <chrono>
|
||||||
|
|
||||||
|
|
||||||
|
class StopWatch {
|
||||||
|
|
||||||
|
private:
|
||||||
|
|
||||||
|
std::chrono::time_point<std::chrono::high_resolution_clock> mBegin;
|
||||||
|
|
||||||
|
public:
|
||||||
|
StopWatch() : mBegin(std::chrono::high_resolution_clock::now()) {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
void reset() {
|
||||||
|
mBegin = std::chrono::high_resolution_clock::now();
|
||||||
|
}
|
||||||
|
|
||||||
|
template<typename Duration=std::chrono::milliseconds>
|
||||||
|
int64_t elapsed() const {
|
||||||
|
return std::chrono::duration_cast<Duration>(std::chrono::high_resolution_clock::now() - mBegin)
|
||||||
|
.count();
|
||||||
|
}
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
#endif //CPP_START_STOP_WATCH_H
|
@ -0,0 +1,20 @@
|
|||||||
|
|
||||||
|
#ifndef CPP_START_LOG_ASPECT_H
|
||||||
|
#define CPP_START_LOG_ASPECT_H
|
||||||
|
|
||||||
|
#include <iostream>
|
||||||
|
|
||||||
|
class LogAspect {
|
||||||
|
|
||||||
|
public:
|
||||||
|
void before(int i) {
|
||||||
|
std::cout << "log info: before: " << i << std::endl;
|
||||||
|
}
|
||||||
|
|
||||||
|
void after(int i) {
|
||||||
|
std::cout << "log info: after: " << i << std::endl;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
#endif //CPP_START_LOG_ASPECT_H
|
@ -0,0 +1,23 @@
|
|||||||
|
|
||||||
|
#ifndef CPP_START_TIME_ELAPSED_ASPECT_H
|
||||||
|
#define CPP_START_TIME_ELAPSED_ASPECT_H
|
||||||
|
|
||||||
|
#include <iostream>
|
||||||
|
#include "../stop_watch.h"
|
||||||
|
|
||||||
|
class TimeElapsedAspect {
|
||||||
|
private:
|
||||||
|
StopWatch mStopWatch;
|
||||||
|
public:
|
||||||
|
|
||||||
|
void before(int a) {
|
||||||
|
mStopWatch.reset();
|
||||||
|
}
|
||||||
|
|
||||||
|
void after(int a) {
|
||||||
|
std::cout << "cost time : " << mStopWatch.elapsed() << " ms" << std::endl;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
#endif //CPP_START_TIME_ELAPSED_ASPECT_H
|
@ -0,0 +1,88 @@
|
|||||||
|
|
||||||
|
#ifndef CPP_START_THREAD_POOL_H
|
||||||
|
#define CPP_START_THREAD_POOL_H
|
||||||
|
|
||||||
|
#include <list>
|
||||||
|
#include <thread>
|
||||||
|
#include <memory>
|
||||||
|
#include <atomic>
|
||||||
|
#include <functional>
|
||||||
|
#include "sync_queue.h"
|
||||||
|
|
||||||
|
class ThreadPool {
|
||||||
|
|
||||||
|
using Task = std::function<void()>;
|
||||||
|
|
||||||
|
private:
|
||||||
|
|
||||||
|
// 线程组
|
||||||
|
std::list<std::shared_ptr<std::thread>> mThreadGroup;
|
||||||
|
|
||||||
|
// 任务队列
|
||||||
|
SyncQueue<Task> mQueue;
|
||||||
|
|
||||||
|
// 运行状态
|
||||||
|
std::atomic_bool mRunning;
|
||||||
|
|
||||||
|
// 标识
|
||||||
|
std::once_flag mFlag;
|
||||||
|
|
||||||
|
private:
|
||||||
|
|
||||||
|
void init(int numThreads) {
|
||||||
|
mRunning = true;
|
||||||
|
for (int i = 0; i < numThreads; ++i) {
|
||||||
|
mThreadGroup.push_back(std::make_shared<std::thread>(&ThreadPool::run, this));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void run() {
|
||||||
|
while (mRunning) {
|
||||||
|
std::list<Task> tasks;
|
||||||
|
mQueue.dequeue(tasks);
|
||||||
|
|
||||||
|
for (auto &task: tasks) {
|
||||||
|
if (!mRunning) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
task();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void stopThreadGroup() {
|
||||||
|
mQueue.stop();
|
||||||
|
mRunning = false;
|
||||||
|
for (const auto &thread: mThreadGroup) {
|
||||||
|
if (thread) {
|
||||||
|
thread->join();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
mThreadGroup.clear();
|
||||||
|
}
|
||||||
|
|
||||||
|
public:
|
||||||
|
ThreadPool(int numThreads = std::thread::hardware_concurrency(), int maxTask = 1000) :
|
||||||
|
mQueue(maxTask) {
|
||||||
|
init(numThreads);
|
||||||
|
}
|
||||||
|
|
||||||
|
~ThreadPool() {
|
||||||
|
stop();
|
||||||
|
}
|
||||||
|
|
||||||
|
void stop() {
|
||||||
|
std::call_once(mFlag, [this] { stopThreadGroup(); });
|
||||||
|
}
|
||||||
|
|
||||||
|
void add(Task &&task) {
|
||||||
|
mQueue.enqueue(std::forward<Task>(task));
|
||||||
|
}
|
||||||
|
|
||||||
|
void add(const Task &task) {
|
||||||
|
mQueue.enqueue(task);
|
||||||
|
}
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif //CPP_START_THREAD_POOL_H
|
Loading…
Reference in new issue