Skip to content

Commit

Permalink
增加全局线程池;版本构建信息
Browse files Browse the repository at this point in the history
  • Loading branch information
fasiondog committed Apr 20, 2020
1 parent c2d3c0b commit 9e0dc2e
Show file tree
Hide file tree
Showing 15 changed files with 205 additions and 35 deletions.
5 changes: 0 additions & 5 deletions config.h.in
Original file line number Diff line number Diff line change
Expand Up @@ -4,11 +4,6 @@

// clang-format off

#define HKU_VERSION "${VERSION}"
#define HKU_VERSION_MAJOR ${VERSION_MAJOR}
#define HKU_VERSION_MINOR ${VERSION_MINOR}
#define HKU_VERSION_ALTER ${VERSION_ALTER}

// support serialization
#define HKU_SUPPORT_SERIALIZATION ${SUPPORT_SERIALIZATION}

Expand Down
8 changes: 5 additions & 3 deletions hikyuu_cpp/hikyuu/GlobalInitializer.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,9 @@

#include <iostream>
#include <H5public.h>
#include <fmt/format.h>
#include "Log.h"
#include "hikyuu.h"
#include "GlobalInitializer.h"
#include "StockManager.h"
#include "debug.h"
Expand All @@ -33,16 +35,16 @@ void GlobalInitializer::init() {
_CrtSetBreakAlloc(-1);
#endif

init_logger();
fmt::print("Initialize hikyuu_{} ...\n", getVersionWithBuild());

initLogger();
DataDriverFactory::init();
auto& sm = StockManager::instance();
}

void GlobalInitializer::clean() {
StockManager::quit();

DataDriverFactory::release();

H5close();

#if USE_SPDLOG_LOGGER
Expand Down
41 changes: 41 additions & 0 deletions hikyuu_cpp/hikyuu/GlobalTaskGroup.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
/*
* GlobalTaskGroup.cpp
*
* Copyright (c) 2019 hikyuu.org
*
* Created on: 2020-4-20
* Author: fasiondog
*/

#include <chrono>
#include "GlobalTaskGroup.h"

namespace hku {

static ThreadPool* g_threadPool;

HKU_API ThreadPool* getGlobalTaskGroup() {
return g_threadPool;
}

void initThreadPool() {
if (!g_threadPool) {
auto cpu_num = std::thread::hardware_concurrency();
if (cpu_num >= 4) {
cpu_num -= 2;
} else if (cpu_num > 1) {
cpu_num--;
}
g_threadPool = new ThreadPool(cpu_num);
}
}

void releaseThreadPool() {
if (g_threadPool) {
g_threadPool->stop();
delete g_threadPool;
g_threadPool = nullptr;
}
}

} /* namespace hku */
38 changes: 38 additions & 0 deletions hikyuu_cpp/hikyuu/GlobalTaskGroup.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
/*
* GlobalTaskGroup.h
*
* Copyright (c) 2019 hikyuu.org
*
* Created on: 2020-4-20
* Author: fasiondog
*/

#pragma
#ifndef HKU_GLOBAL_TASK_GROUP
#define HKU_GLOBAL_TASK_GROUP

#include "utilities/thread/ThreadPool.h"

#ifndef HKU_API
#define HKU_API
#endif

namespace hku {

/**
* 获取全局线程池任务组
* @note 请使用 future 获取任务返回
*/
HKU_API ThreadPool* getGlobalTaskGroup();

/*
* 内部函数,初始化全局任务组
*/
void initThreadPool();

/* 内部函数,初始化全局任务组 */
void releaseThreadPool();

} /* namespace hku */

#endif /* HKU_GLOBAL_TASK_GROUP */
6 changes: 3 additions & 3 deletions hikyuu_cpp/hikyuu/Log.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@ std::shared_ptr<spdlog::logger> getHikyuuLogger() {
*********************************************/
#if USE_SPDLOG_LOGGER
#if HKU_USE_SPDLOG_ASYNC_LOGGER
void init_logger() {
void initLogger() {
// auto stdout_sink = std::make_shared<spdlog::sinks::ostream_sink_mt>(std::cout, true);
auto stdout_sink = std::make_shared<spdlog::sinks::stdout_color_sink_mt>();
stdout_sink->set_level(spdlog::level::trace);
Expand All @@ -56,7 +56,7 @@ void init_logger() {

#else /* #if HKU_USE_SPDLOG_ASYNC_LOGGER */

void init_logger() {
void initLogger() {
auto stdout_sink = std::make_shared<spdlog::sinks::stdout_color_sink_mt>();
stdout_sink->set_level(spdlog::level::trace);
auto logger = std::make_shared<spdlog::logger>("hikyuu", stdout_sink);
Expand All @@ -77,7 +77,7 @@ void set_log_level(LOG_LEVEL level) {
/**********************************************
* Use SPDLOG for logging
*********************************************/
void init_logger() {}
void initLogger() {}

void set_log_level(LOG_LEVEL level) {
g_log_level = level;
Expand Down
6 changes: 3 additions & 3 deletions hikyuu_cpp/hikyuu/Log.h
Original file line number Diff line number Diff line change
Expand Up @@ -87,9 +87,9 @@ std::shared_ptr<spdlog::logger> HKU_API getHikyuuLogger();
#define HKU_FATAL(...) SPDLOG_LOGGER_CRITICAL(hku::getHikyuuLogger(), __VA_ARGS__)

#if HKU_USE_SPDLOG_ASYNC_LOGGER
void init_logger();
void initLogger();
#else
void init_logger();
void initLogger();
#endif

#else
Expand All @@ -105,7 +105,7 @@ enum LOG_LEVEL {

LOG_LEVEL HKU_API get_log_level();
void HKU_API set_log_level(LOG_LEVEL level);
void init_logger();
void initLogger();

#if LOG_ACTIVE_LEVEL <= 0
#define HKU_TRACE(...) \
Expand Down
40 changes: 27 additions & 13 deletions hikyuu_cpp/hikyuu/StockManager.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -7,12 +7,14 @@

#include "GlobalInitializer.h"
#include <chrono>
#include <fmt/format.h>
#include <boost/lexical_cast.hpp>
#include <boost/algorithm/string.hpp>

#include "utilities/IniParser.h"
#include "utilities/util.h"
#include "StockManager.h"
#include "GlobalTaskGroup.h"
#include "data_driver/KDataTempCsvDriver.h"
#include "data_driver/base_info/sqlite/SQLiteBaseInfoDriver.h"
#include "data_driver/base_info/mysql/MySQLBaseInfoDriver.h"
Expand All @@ -26,16 +28,21 @@ namespace hku {
StockManager* StockManager::m_sm = nullptr;

void StockManager::quit() {
// Cannot use log output when exiting!
// HKU_TRACE("Quit Hikyuu system!\n");
releaseThreadPool();
if (m_sm) {
std::cout << "Quit Hikyuu system!\n" << std::endl;
delete m_sm;
m_sm = nullptr;
}
}

StockManager::~StockManager() {}
StockManager::StockManager() {}
StockManager::~StockManager() {
auto tg = getGlobalTaskGroup();
if (tg && !tg->done()) {
releaseThreadPool();
}
fmt::print("Quit Hikyuu system!\n\n");
}

StockManager& StockManager::instance() {
if (!m_sm) {
Expand Down Expand Up @@ -67,15 +74,21 @@ Parameter default_other_param() {
return param;
}

void StockManager::init(const Parameter& baseInfoParam, const Parameter& blockParam, const Parameter& kdataParam,
const Parameter& preloadParam, const Parameter& hikyuuParam) {
void StockManager::init(const Parameter& baseInfoParam, const Parameter& blockParam,
const Parameter& kdataParam, const Parameter& preloadParam,
const Parameter& hikyuuParam) {
m_baseInfoDriverParam = baseInfoParam;
m_blockDriverParam = blockParam;
m_kdataDriverParam = kdataParam;
m_preloadParam = preloadParam;
m_hikyuuParam = hikyuuParam;

//获取临时路径信息
// 创建内部线程池
// 不能同过 GlobalInitializer 初始化全局线程池
// 原因是 std::thread 无法在 dllmain 中创建使用,会造成死锁
initThreadPool();

// 获取临时路径信息
try {
m_tmpdir = hikyuuParam.get<string>("tmpdir");
} catch (...) {
Expand Down Expand Up @@ -111,7 +124,8 @@ void StockManager::init(const Parameter& baseInfoParam, const Parameter& blockPa
setKDataDriver(kdata_driver);

// add special Market, for temp csv file
m_marketInfoDict["TMP"] = MarketInfo("TMP", "Temp Csv file", "temp load from csv file", "000001", Null<Datetime>());
m_marketInfoDict["TMP"] =
MarketInfo("TMP", "Temp Csv file", "temp load from csv file", "000001", Null<Datetime>());

std::chrono::duration<double> sec = std::chrono::system_clock::now() - start_time;
HKU_INFO("{:<.2f}s Loaded Data.", sec.count());
Expand Down Expand Up @@ -336,13 +350,13 @@ DatetimeList StockManager::getTradingCalendar(const KQuery& query, const string&
return result;
}

Stock StockManager::addTempCsvStock(const string& code, const string& day_filename, const string& min_filename,
price_t tick, price_t tickValue, int precision, size_t minTradeNumber,
size_t maxTradeNumber) {
Stock StockManager::addTempCsvStock(const string& code, const string& day_filename,
const string& min_filename, price_t tick, price_t tickValue,
int precision, size_t minTradeNumber, size_t maxTradeNumber) {
string new_code(code);
to_upper(new_code);
Stock result("TMP", new_code, day_filename, STOCKTYPE_TMP, true, Datetime(199901010000), Null<Datetime>(), tick,
tickValue, precision, minTradeNumber, maxTradeNumber);
Stock result("TMP", new_code, day_filename, STOCKTYPE_TMP, true, Datetime(199901010000),
Null<Datetime>(), tick, tickValue, precision, minTradeNumber, maxTradeNumber);

KDataTempCsvDriver* p = new KDataTempCsvDriver(day_filename, min_filename);
result.setKDataDriver(KDataDriverPtr(p));
Expand Down
11 changes: 6 additions & 5 deletions hikyuu_cpp/hikyuu/StockManager.h
Original file line number Diff line number Diff line change
Expand Up @@ -39,8 +39,8 @@ class HKU_API StockManager {
* @param preloadParam
* @param hikyuuParam
*/
void init(const Parameter& baseInfoParam, const Parameter& blockParam, const Parameter& kdataParam,
const Parameter& preloadParam = default_preload_param(),
void init(const Parameter& baseInfoParam, const Parameter& blockParam,
const Parameter& kdataParam, const Parameter& preloadParam = default_preload_param(),
const Parameter& hikyuuParam = default_other_param());

/** 主动退出并释放资源 */
Expand Down Expand Up @@ -153,8 +153,9 @@ class HKU_API StockManager {
* @param maxTradeNumber 单笔最大交易量,默认1000000
* @return
*/
Stock addTempCsvStock(const string& code, const string& day_filename, const string& min_filename,
price_t tick = 0.01, price_t tickValue = 0.01, int precision = 2, size_t minTradeNumber = 1,
Stock addTempCsvStock(const string& code, const string& day_filename,
const string& min_filename, price_t tick = 0.01, price_t tickValue = 0.01,
int precision = 2, size_t minTradeNumber = 1,
size_t maxTradeNumber = 1000000);

/**
Expand All @@ -173,7 +174,7 @@ class HKU_API StockManager {
}

private:
StockManager() {}
StockManager();

private:
static StockManager* m_sm;
Expand Down
16 changes: 16 additions & 0 deletions hikyuu_cpp/hikyuu/hikyuu.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,10 @@
* Author: fasiondog
*/

#include <fmt/format.h>
#include "utilities/IniParser.h"
#include "hikyuu.h"
#include "version.h"

namespace hku {

Expand Down Expand Up @@ -68,4 +70,18 @@ string getVersion() {
return HKU_VERSION;
}

std::string HKU_API getVersionWithBuild() {
#if defined(__arm__)
return fmt::format("{}_{}_arm", HKU_VERSION, HKU_VERSION_BUILD);
#elif defined(__aarch64__)
return fmt::format("{}_{}_aarch64", HKU_VERSION, HKU_VERSION_BUILD);
#elif defined(__x86_64__) || defined(_WIN64)
return fmt::format("{}_{}_x64", HKU_VERSION, HKU_VERSION_BUILD);
#elif defined(__i386__) || defined(_WIN32)
return fmt::format("{}_{}_i386", HKU_VERSION, HKU_VERSION_BUILD);
#else
return fmt::format("{}_{}_unknow_arch", HKU_VERSION, HKU_VERSION_BUILD);
#endif
}

} // namespace hku
5 changes: 5 additions & 0 deletions hikyuu_cpp/hikyuu/hikyuu.h
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,11 @@ void HKU_API hikyuu_init(const string& config_file_name);
*/
string HKU_API getVersion();

/**
* 获取详细版本号,包含构建时间
*/
std::string HKU_API getVersionWithBuild();

} // namespace hku

#endif /* HIKYUU_H_ */
17 changes: 15 additions & 2 deletions hikyuu_cpp/hikyuu/utilities/thread/ThreadPool.h
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@
#ifndef HIKYUU_UTILITIES_THREAD_THREADPOOL_H
#define HIKYUU_UTILITIES_THREAD_THREADPOOL_H

//#include <fmt/format.h>
#include <future>
#include <thread>
#include <chrono>
Expand Down Expand Up @@ -84,11 +85,22 @@ class ThreadPool {
return res;
}

/** 返回线程池结束状态 */
bool done() const {
return m_done;
}

/**
* 等待各线程完成当前执行的任务后立即结束退出
*/
void stop() {
m_done = true;

// 同时加入结束任务指示,以便在dll退出时也能够终止
for (size_t i = 0; i < m_worker_num; i++) {
m_queues[i]->push_front(std::move(FuncWrapper()));
}

m_cv.notify_all(); // 唤醒所有工作线程
for (size_t i = 0; i < m_worker_num; i++) {
if (m_threads[i].joinable()) {
Expand Down Expand Up @@ -134,8 +146,8 @@ class ThreadPool {

// 线程本地变量
inline static thread_local WorkStealQueue* m_local_work_queue = nullptr; // 本地任务队列
inline static thread_local size_t m_index = 0; //在线程池中的序号
inline static thread_local bool m_thread_need_stop = false; // 线程停止运行指示
inline static thread_local size_t m_index = 0; //在线程池中的序号
inline static thread_local bool m_thread_need_stop = false; // 线程停止运行指示

void worker_thread(size_t index) {
m_thread_need_stop = false;
Expand All @@ -144,6 +156,7 @@ class ThreadPool {
while (!m_thread_need_stop && !m_done) {
run_pending_task();
}
// fmt::print("thread ({}) finished!\n", std::this_thread::get_id());
}

void run_pending_task() {
Expand Down
Loading

0 comments on commit 9e0dc2e

Please sign in to comment.