hikyuu 2.7.0__py3-none-manylinux2014_aarch64.whl → 2.7.3__py3-none-manylinux2014_aarch64.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- hikyuu/__init__.py +25 -7
- hikyuu/__init__.pyi +23 -12
- hikyuu/analysis/__init__.pyi +6 -1
- hikyuu/analysis/analysis.pyi +7 -2
- hikyuu/core.pyi +8 -3
- hikyuu/cpp/core310.pyi +94 -24
- hikyuu/cpp/core310.so +0 -0
- hikyuu/cpp/core311.pyi +94 -24
- hikyuu/cpp/core311.so +0 -0
- hikyuu/cpp/core312.pyi +94 -24
- hikyuu/cpp/core312.so +0 -0
- hikyuu/cpp/core313.pyi +94 -24
- hikyuu/cpp/core313.so +0 -0
- hikyuu/cpp/i18n/zh_CN/hikyuu.mo +0 -0
- hikyuu/cpp/i18n/zh_CN/hikyuu_plugin.mo +0 -0
- hikyuu/cpp/libboost_atomic.so +0 -0
- hikyuu/cpp/libboost_atomic.so.1.90.0 +0 -0
- hikyuu/cpp/{libboost_charconv-mt.so → libboost_charconv.so} +0 -0
- hikyuu/cpp/{libboost_charconv-mt.so.1.88.0 → libboost_charconv.so.1.90.0} +0 -0
- hikyuu/cpp/libboost_chrono.so +0 -0
- hikyuu/cpp/libboost_chrono.so.1.90.0 +0 -0
- hikyuu/cpp/libboost_container.so +0 -0
- hikyuu/cpp/libboost_container.so.1.90.0 +0 -0
- hikyuu/cpp/libboost_date_time.so +0 -0
- hikyuu/cpp/libboost_date_time.so.1.90.0 +0 -0
- hikyuu/cpp/libboost_locale.so +0 -0
- hikyuu/cpp/libboost_locale.so.1.90.0 +0 -0
- hikyuu/cpp/libboost_random.so +0 -0
- hikyuu/cpp/libboost_random.so.1.90.0 +0 -0
- hikyuu/cpp/libboost_serialization.so +0 -0
- hikyuu/cpp/libboost_serialization.so.1.90.0 +0 -0
- hikyuu/cpp/libboost_thread.so +0 -0
- hikyuu/cpp/libboost_thread.so.1.90.0 +0 -0
- hikyuu/cpp/libboost_wserialization.so +0 -0
- hikyuu/cpp/libboost_wserialization.so.1.90.0 +0 -0
- hikyuu/cpp/libhikyuu.so +0 -0
- hikyuu/cpp/libsqlite3.so +0 -0
- hikyuu/data/clickhouse_upgrade/0001.sql +2 -0
- hikyuu/data/common_clickhouse.py +1 -3
- hikyuu/data/download_block.py +1 -1
- hikyuu/data/hku_config_template.py +30 -3
- hikyuu/data/mysql_upgrade/0029.sql +2 -0
- hikyuu/data/pytdx_to_clickhouse.py +86 -32
- hikyuu/data/pytdx_to_h5.py +73 -28
- hikyuu/data/pytdx_to_mysql.py +65 -21
- hikyuu/data/pytdx_weight_to_clickhouse.py +2 -0
- hikyuu/data/pytdx_weight_to_mysql.py +2 -0
- hikyuu/data/pytdx_weight_to_sqlite.py +2 -0
- hikyuu/data/sqlite_upgrade/0029.sql +4 -0
- hikyuu/data/tdx_to_clickhouse.py +2 -2
- hikyuu/data/tdx_to_h5.py +11 -11
- hikyuu/data/tdx_to_mysql.py +2 -2
- hikyuu/draw/drawplot/bokeh_draw.pyi +14 -7
- hikyuu/draw/drawplot/echarts_draw.pyi +14 -7
- hikyuu/draw/drawplot/matplotlib_draw.py +8 -2
- hikyuu/draw/drawplot/matplotlib_draw.pyi +14 -7
- hikyuu/extend.pyi +8 -3
- hikyuu/gui/HikyuuTDX.py +42 -3
- hikyuu/gui/data/MainWindow.py +189 -129
- hikyuu/hub.pyi +6 -6
- hikyuu/include/hikyuu/StockManager.h +17 -2
- hikyuu/include/hikyuu/StrategyContext.h +4 -4
- hikyuu/include/hikyuu/data_driver/BaseInfoDriver.h +2 -1
- hikyuu/include/hikyuu/data_driver/KDataDriver.h +2 -4
- hikyuu/include/hikyuu/data_driver/kdata/mysql/MySQLKDataDriver.h +5 -1
- hikyuu/include/hikyuu/data_driver/kdata/sqlite/SQLiteKDataDriver.h +1 -1
- hikyuu/include/hikyuu/global/sysinfo.h +24 -5
- hikyuu/include/hikyuu/indicator/IndicatorImp.h +1 -1
- hikyuu/include/hikyuu/plugin/KDataToClickHouseImporter.h +40 -0
- hikyuu/include/hikyuu/plugin/KDataToMySQLImporter.h +40 -0
- hikyuu/include/hikyuu/plugin/checkdata.h +20 -0
- hikyuu/include/hikyuu/plugin/extind.h +3 -0
- hikyuu/include/hikyuu/plugin/hkuextra.h +2 -0
- hikyuu/include/hikyuu/plugin/interface/CheckDataPluginInterface.h +25 -0
- hikyuu/include/hikyuu/plugin/interface/HkuExtraPluginInterface.h +2 -0
- hikyuu/include/hikyuu/plugin/interface/ImportKDataToClickHousePluginInterface.h +44 -0
- hikyuu/include/hikyuu/plugin/interface/ImportKDataToMySQLPluginInterface.h +42 -0
- hikyuu/include/hikyuu/plugin/interface/plugins.h +6 -0
- hikyuu/include/hikyuu/python/convert_any.h +9 -6
- hikyuu/include/hikyuu/python/pybind_utils.h +1 -1
- hikyuu/include/hikyuu/strategy/Strategy.h +1 -1
- hikyuu/include/hikyuu/trade_manage/TradeManagerBase.h +0 -1
- hikyuu/include/hikyuu/trade_manage/TradeRecord.h +2 -1
- hikyuu/include/hikyuu/trade_sys/allocatefunds/AllocateFundsBase.h +0 -1
- hikyuu/include/hikyuu/trade_sys/allocatefunds/build_in.h +1 -0
- hikyuu/include/hikyuu/trade_sys/allocatefunds/crt/AF_FixedAmount.h +26 -0
- hikyuu/include/hikyuu/trade_sys/allocatefunds/imp/FixAmountFunds.h +18 -0
- hikyuu/include/hikyuu/trade_sys/condition/ConditionBase.h +0 -1
- hikyuu/include/hikyuu/trade_sys/environment/EnvironmentBase.h +0 -1
- hikyuu/include/hikyuu/trade_sys/moneymanager/MoneyManagerBase.h +0 -1
- hikyuu/include/hikyuu/trade_sys/multifactor/MultiFactorBase.h +0 -1
- hikyuu/include/hikyuu/trade_sys/multifactor/NormalizeBase.h +0 -1
- hikyuu/include/hikyuu/trade_sys/multifactor/ScoresFilterBase.h +0 -1
- hikyuu/include/hikyuu/trade_sys/portfolio/Portfolio.h +13 -13
- hikyuu/include/hikyuu/trade_sys/profitgoal/ProfitGoalBase.h +9 -11
- hikyuu/include/hikyuu/trade_sys/selector/SelectorBase.h +0 -1
- hikyuu/include/hikyuu/trade_sys/signal/SignalBase.h +0 -1
- hikyuu/include/hikyuu/trade_sys/slippage/SlippageBase.h +0 -1
- hikyuu/include/hikyuu/trade_sys/stoploss/StoplossBase.h +0 -1
- hikyuu/include/hikyuu/trade_sys/system/System.h +1 -2
- hikyuu/include/hikyuu/utilities/Log.h +6 -7
- hikyuu/include/hikyuu/utilities/Parameter.h +17 -0
- hikyuu/include/hikyuu/utilities/config.h +28 -0
- hikyuu/include/hikyuu/utilities/plugin/PluginBase.h +17 -2
- hikyuu/include/hikyuu/utilities/plugin/PluginManager.h +41 -22
- hikyuu/include/hikyuu/utilities/thread/GlobalStealThreadPool.h +1 -2
- hikyuu/include/hikyuu/utilities/thread/GlobalThreadPool.h +1 -1
- hikyuu/include/hikyuu/utilities/thread/MQStealThreadPool.h +286 -0
- hikyuu/include/hikyuu/utilities/thread/MQThreadPool.h +1 -0
- hikyuu/include/hikyuu/utilities/thread/StealThreadPool.h +297 -0
- hikyuu/include/hikyuu/utilities/thread/ThreadPool.h +1 -0
- hikyuu/include/hikyuu/utilities/thread/WorkStealQueue.h +9 -8
- hikyuu/include/hikyuu/utilities/thread/algorithm.h +64 -14
- hikyuu/include/hikyuu/version.h +4 -4
- hikyuu/plugin/libbacktest.so +0 -0
- hikyuu/plugin/libcheckdata.so +0 -0
- hikyuu/plugin/libclickhousedriver.so +0 -0
- hikyuu/plugin/libdataserver.so +0 -0
- hikyuu/plugin/libdataserver_parquet.so +0 -0
- hikyuu/plugin/libdevice.so +0 -0
- hikyuu/plugin/libextind.so +0 -0
- hikyuu/plugin/libhkuextra.so +0 -0
- hikyuu/plugin/libimport2ch.so +0 -0
- hikyuu/plugin/libimport2hdf5.so +0 -0
- hikyuu/plugin/libimport2mysql.so +0 -0
- hikyuu/plugin/libtmreport.so +0 -0
- hikyuu/trade_manage/__init__.pyi +12 -7
- hikyuu/trade_manage/trade.pyi +12 -7
- hikyuu/trade_sys/trade_sys.py +54 -5
- hikyuu/util/__init__.pyi +1 -1
- hikyuu/util/singleton.pyi +1 -1
- {hikyuu-2.7.0.dist-info → hikyuu-2.7.3.dist-info}/METADATA +10 -4
- {hikyuu-2.7.0.dist-info → hikyuu-2.7.3.dist-info}/RECORD +136 -114
- hikyuu/cpp/libboost_chrono-mt.so +0 -0
- hikyuu/cpp/libboost_chrono-mt.so.1.88.0 +0 -0
- hikyuu/cpp/libboost_date_time-mt.so +0 -0
- hikyuu/cpp/libboost_date_time-mt.so.1.88.0 +0 -0
- hikyuu/cpp/libboost_serialization-mt.so +0 -0
- hikyuu/cpp/libboost_serialization-mt.so.1.88.0 +0 -0
- hikyuu/cpp/libboost_system-mt.so +0 -0
- hikyuu/cpp/libboost_system-mt.so.1.88.0 +0 -0
- hikyuu/cpp/libboost_thread-mt.so +0 -0
- hikyuu/cpp/libboost_thread-mt.so.1.88.0 +0 -0
- hikyuu/cpp/libboost_wserialization-mt.so +0 -0
- hikyuu/cpp/libboost_wserialization-mt.so.1.88.0 +0 -0
- hikyuu/data/pytdx_to_taos.py +0 -736
- {hikyuu-2.7.0.dist-info → hikyuu-2.7.3.dist-info}/WHEEL +0 -0
- {hikyuu-2.7.0.dist-info → hikyuu-2.7.3.dist-info}/entry_points.txt +0 -0
- {hikyuu-2.7.0.dist-info → hikyuu-2.7.3.dist-info}/top_level.txt +0 -0
|
@@ -36,7 +36,7 @@ class HKU_API WalkForwardSystem;
|
|
|
36
36
|
* 交易系统基类
|
|
37
37
|
* @ingroup System
|
|
38
38
|
*/
|
|
39
|
-
class HKU_API System {
|
|
39
|
+
class HKU_API System : public enable_shared_from_this<System> {
|
|
40
40
|
PARAMETER_SUPPORT_WITH_CHECK
|
|
41
41
|
friend class HKU_API Portfolio;
|
|
42
42
|
friend class HKU_API AllocateFundsBase;
|
|
@@ -276,7 +276,6 @@ public:
|
|
|
276
276
|
// 处理延迟买入请求,仅供 PF 调用
|
|
277
277
|
virtual TradeRecord pfProcessDelayBuyRequest(const Datetime& date);
|
|
278
278
|
|
|
279
|
-
protected:
|
|
280
279
|
virtual bool isPythonObject() const {
|
|
281
280
|
return false;
|
|
282
281
|
}
|
|
@@ -343,13 +343,12 @@ std::shared_ptr<spdlog::logger> HKU_UTILS_API getHikyuuLogger();
|
|
|
343
343
|
}
|
|
344
344
|
|
|
345
345
|
/** 用于 catch (...) 中打印,减少编译后代码大小 */
|
|
346
|
-
|
|
347
|
-
#define
|
|
348
|
-
#define
|
|
349
|
-
#define
|
|
350
|
-
#define
|
|
351
|
-
#define
|
|
352
|
-
#define HKU_FATAL_UNKNOWN HKU_FATAL("{}", g_unknown_error_msg)
|
|
346
|
+
#define HKU_THROW_UNKNOWN HKU_THROW("Unknown error!")
|
|
347
|
+
#define HKU_TRACE_UNKNOWN HKU_TRACE("Unknown error!")
|
|
348
|
+
#define HKU_DEBUG_UNKNOWN HKU_DEBUG("Unknown error!")
|
|
349
|
+
#define HKU_INFO_UNKNOWN HKU_INFO("Unknown error!");
|
|
350
|
+
#define HKU_ERROR_UNKNOWN HKU_ERROR("Unknown error!");
|
|
351
|
+
#define HKU_FATAL_UNKNOWN HKU_FATAL("Unknown error!");
|
|
353
352
|
|
|
354
353
|
#if CPP_STANDARD >= CPP_STANDARD_20
|
|
355
354
|
#define CLASS_LOGGER_IMP(cls) \
|
|
@@ -503,6 +503,23 @@ inline void Parameter::set(const string& name, const boost::any& value) {
|
|
|
503
503
|
m_params[name] = value;
|
|
504
504
|
}
|
|
505
505
|
|
|
506
|
+
template <>
|
|
507
|
+
inline int64_t Parameter::get(const string& name) const {
|
|
508
|
+
param_map_t::const_iterator iter;
|
|
509
|
+
iter = m_params.find(name);
|
|
510
|
+
if (iter == m_params.end()) {
|
|
511
|
+
throw std::out_of_range("out_of_range in Parameter::get : " + name);
|
|
512
|
+
}
|
|
513
|
+
try {
|
|
514
|
+
if (iter->second.type() == typeid(int)) {
|
|
515
|
+
return boost::any_cast<int>(iter->second);
|
|
516
|
+
}
|
|
517
|
+
return boost::any_cast<int64_t>(iter->second);
|
|
518
|
+
} catch (...) {
|
|
519
|
+
throw std::runtime_error("failed conversion param: " + name);
|
|
520
|
+
}
|
|
521
|
+
}
|
|
522
|
+
|
|
506
523
|
HKU_API bool operator==(const Parameter&, const Parameter&);
|
|
507
524
|
HKU_API bool operator!=(const Parameter&, const Parameter&);
|
|
508
525
|
HKU_API bool operator<(const Parameter&, const Parameter&);
|
|
@@ -6,33 +6,61 @@
|
|
|
6
6
|
|
|
7
7
|
// clang-format off
|
|
8
8
|
|
|
9
|
+
#ifndef HKU_ENABLE_MYSQL
|
|
9
10
|
#define HKU_ENABLE_MYSQL 1
|
|
10
11
|
#if HKU_ENABLE_MYSQL && HKU_OS_WINDOWS
|
|
11
12
|
#ifndef NOMINMAX
|
|
12
13
|
#define NOMINMAX
|
|
13
14
|
#endif
|
|
14
15
|
#endif
|
|
16
|
+
#endif
|
|
15
17
|
|
|
18
|
+
#ifndef HKU_ENABLE_SQLITE
|
|
16
19
|
#define HKU_ENABLE_SQLITE 1
|
|
20
|
+
#endif
|
|
21
|
+
#ifndef HKU_ENABLE_SQLCIPHER
|
|
17
22
|
#define HKU_ENABLE_SQLCIPHER 0
|
|
23
|
+
#endif
|
|
24
|
+
#ifndef HKU_SQL_TRACE
|
|
18
25
|
/* #define HKU_SQL_TRACE 0 */
|
|
26
|
+
#endif
|
|
19
27
|
|
|
28
|
+
#ifndef HKU_SUPPORT_DATETIME
|
|
20
29
|
#define HKU_SUPPORT_DATETIME 1
|
|
30
|
+
#endif
|
|
21
31
|
|
|
32
|
+
#ifndef HKU_ENABLE_INI_PARSER
|
|
22
33
|
#define HKU_ENABLE_INI_PARSER 1
|
|
34
|
+
#endif
|
|
23
35
|
|
|
36
|
+
#ifndef HKU_ENABLE_STACK_TRACE
|
|
24
37
|
#define HKU_ENABLE_STACK_TRACE 0
|
|
38
|
+
#endif
|
|
25
39
|
|
|
40
|
+
#ifndef HKU_CLOSE_SPEND_TIME
|
|
26
41
|
#define HKU_CLOSE_SPEND_TIME 0
|
|
42
|
+
#endif
|
|
27
43
|
|
|
44
|
+
#ifndef HKU_USE_SPDLOG_ASYNC_LOGGER
|
|
28
45
|
#define HKU_USE_SPDLOG_ASYNC_LOGGER 0
|
|
46
|
+
#endif
|
|
47
|
+
#ifndef HKU_LOG_ACTIVE_LEVEL
|
|
29
48
|
#define HKU_LOG_ACTIVE_LEVEL 2
|
|
49
|
+
#endif
|
|
30
50
|
|
|
51
|
+
#ifndef HKU_ENABLE_HTTP_CLIENT
|
|
31
52
|
#define HKU_ENABLE_HTTP_CLIENT 1
|
|
53
|
+
#endif
|
|
54
|
+
#ifndef HKU_ENABLE_HTTP_CLIENT_SSL
|
|
32
55
|
#define HKU_ENABLE_HTTP_CLIENT_SSL 0
|
|
56
|
+
#endif
|
|
57
|
+
#ifndef HKU_ENABLE_HTTP_CLIENT_ZIP
|
|
33
58
|
#define HKU_ENABLE_HTTP_CLIENT_ZIP 0
|
|
59
|
+
#endif
|
|
34
60
|
|
|
61
|
+
#ifndef HKU_ENABLE_NODE
|
|
35
62
|
#define HKU_ENABLE_NODE 1
|
|
63
|
+
#endif
|
|
36
64
|
|
|
37
65
|
// clang-format on
|
|
38
66
|
|
|
@@ -12,6 +12,7 @@
|
|
|
12
12
|
#include <string>
|
|
13
13
|
#include "hikyuu/utilities/config.h"
|
|
14
14
|
#include "hikyuu/utilities/osdef.h"
|
|
15
|
+
#include "hikyuu/utilities/Log.h"
|
|
15
16
|
|
|
16
17
|
namespace hku {
|
|
17
18
|
|
|
@@ -35,12 +36,26 @@ public:
|
|
|
35
36
|
#if HKU_OS_WINDOWS
|
|
36
37
|
#define HKU_PLUGIN_DEFINE(plugin) \
|
|
37
38
|
extern "C" __declspec(dllexport) hku::PluginBase* createPlugin() { \
|
|
38
|
-
|
|
39
|
+
try { \
|
|
40
|
+
return new plugin(); \
|
|
41
|
+
} catch (const std::exception& e) { \
|
|
42
|
+
HKU_ERROR("{}", e.what()); \
|
|
43
|
+
return nullptr; \
|
|
44
|
+
} catch (...) { \
|
|
45
|
+
return nullptr; \
|
|
46
|
+
} \
|
|
39
47
|
}
|
|
40
48
|
#else
|
|
41
49
|
#define HKU_PLUGIN_DEFINE(plugin) \
|
|
42
50
|
extern "C" hku::PluginBase* createPlugin() { \
|
|
43
|
-
|
|
51
|
+
try { \
|
|
52
|
+
return new plugin(); \
|
|
53
|
+
} catch (const std::exception& e) { \
|
|
54
|
+
HKU_ERROR("{}", e.what()); \
|
|
55
|
+
return nullptr; \
|
|
56
|
+
} catch (...) { \
|
|
57
|
+
return nullptr; \
|
|
58
|
+
} \
|
|
44
59
|
}
|
|
45
60
|
#endif
|
|
46
61
|
|
|
@@ -10,7 +10,7 @@
|
|
|
10
10
|
#include <string>
|
|
11
11
|
#include <memory>
|
|
12
12
|
#include <unordered_map>
|
|
13
|
-
#include <
|
|
13
|
+
#include <shared_mutex>
|
|
14
14
|
#include "hikyuu/utilities/Log.h"
|
|
15
15
|
#include "hikyuu/utilities/plugin/PluginLoader.h"
|
|
16
16
|
|
|
@@ -38,35 +38,54 @@ public:
|
|
|
38
38
|
}
|
|
39
39
|
|
|
40
40
|
template <typename PluginInterfaceT>
|
|
41
|
-
PluginInterfaceT* getPlugin(const std::string& pluginname) noexcept
|
|
41
|
+
PluginInterfaceT* getPlugin(const std::string& pluginname) noexcept {
|
|
42
|
+
PluginInterfaceT* ret{nullptr};
|
|
43
|
+
try {
|
|
44
|
+
{
|
|
45
|
+
std::shared_lock<std::shared_mutex> read_lock(m_mutex);
|
|
46
|
+
auto it = m_plugins.find(pluginname);
|
|
47
|
+
if (it != m_plugins.end()) {
|
|
48
|
+
ret = it->second->instance<PluginInterfaceT>();
|
|
49
|
+
return ret;
|
|
50
|
+
}
|
|
51
|
+
}
|
|
42
52
|
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
53
|
+
std::unique_ptr<PluginLoader> loader = std::make_unique<PluginLoader>(m_plugin_path);
|
|
54
|
+
if (!loader->load(pluginname)) {
|
|
55
|
+
HKU_DEBUG("Load plugin {} failed: {}", pluginname, loader->getFileName(pluginname));
|
|
56
|
+
return ret;
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
{
|
|
60
|
+
std::unique_lock<std::shared_mutex> write_lock(m_mutex);
|
|
61
|
+
auto it = m_plugins.find(pluginname);
|
|
62
|
+
if (it != m_plugins.end()) {
|
|
63
|
+
// 复用已插入的插件实例
|
|
64
|
+
ret = it->second->instance<PluginInterfaceT>();
|
|
65
|
+
} else {
|
|
66
|
+
// 插入新加载的插件
|
|
67
|
+
auto [it, success] =
|
|
68
|
+
m_plugins.insert(std::make_pair(pluginname, std::move(loader)));
|
|
69
|
+
if (success) {
|
|
70
|
+
ret = it->second->instance<PluginInterfaceT>();
|
|
71
|
+
}
|
|
72
|
+
}
|
|
73
|
+
return ret;
|
|
52
74
|
}
|
|
75
|
+
} catch (const std::exception& e) {
|
|
76
|
+
HKU_ERROR("Load plugin {} failed: {}", pluginname, e.what());
|
|
77
|
+
ret = nullptr;
|
|
78
|
+
} catch (...) {
|
|
79
|
+
HKU_ERROR("Load plugin {} failed: unknown exception", pluginname);
|
|
80
|
+
ret = nullptr;
|
|
53
81
|
}
|
|
54
|
-
return
|
|
82
|
+
return ret;
|
|
55
83
|
}
|
|
56
84
|
|
|
57
85
|
private:
|
|
58
86
|
std::string m_plugin_path;
|
|
59
87
|
std::unordered_map<std::string, std::unique_ptr<PluginLoader>> m_plugins;
|
|
60
|
-
std::
|
|
88
|
+
std::shared_mutex m_mutex;
|
|
61
89
|
};
|
|
62
90
|
|
|
63
|
-
template <typename PluginInterfaceT>
|
|
64
|
-
PluginInterfaceT* PluginManager::getPlugin(const std::string& pluginname) noexcept {
|
|
65
|
-
auto it = m_plugins.find(pluginname);
|
|
66
|
-
if (it == m_plugins.end()) {
|
|
67
|
-
it = load(pluginname);
|
|
68
|
-
}
|
|
69
|
-
return it != m_plugins.end() ? it->second->instance<PluginInterfaceT>() : nullptr;
|
|
70
|
-
}
|
|
71
|
-
|
|
72
91
|
} // namespace hku
|
|
@@ -0,0 +1,286 @@
|
|
|
1
|
+
/*
|
|
2
|
+
* StealMQStealThreadPool.h
|
|
3
|
+
*
|
|
4
|
+
* Copyright (c) 2019 hikyuu.org
|
|
5
|
+
*
|
|
6
|
+
* Created on: 2019-9-16
|
|
7
|
+
* Author: fasiondog
|
|
8
|
+
*/
|
|
9
|
+
|
|
10
|
+
#pragma once
|
|
11
|
+
|
|
12
|
+
#include <future>
|
|
13
|
+
#include <thread>
|
|
14
|
+
#include <chrono>
|
|
15
|
+
#include <vector>
|
|
16
|
+
#include "FuncWrapper.h"
|
|
17
|
+
#include "MQStealQueue.h"
|
|
18
|
+
#include "InterruptFlag.h"
|
|
19
|
+
#include "../cppdef.h"
|
|
20
|
+
|
|
21
|
+
#ifdef __GNUC__
|
|
22
|
+
#pragma GCC diagnostic push
|
|
23
|
+
#pragma GCC diagnostic ignored "-Wsign-compare"
|
|
24
|
+
#endif
|
|
25
|
+
#ifndef HKU_UTILS_API
|
|
26
|
+
#define HKU_UTILS_API
|
|
27
|
+
#endif
|
|
28
|
+
|
|
29
|
+
namespace hku {
|
|
30
|
+
|
|
31
|
+
/**
|
|
32
|
+
* @brief 无集中队列多队列偷取任务池
|
|
33
|
+
* @ingroup ThreadPool
|
|
34
|
+
*/
|
|
35
|
+
#ifdef _MSC_VER
|
|
36
|
+
class MQStealThreadPool {
|
|
37
|
+
#else
|
|
38
|
+
class HKU_UTILS_API MQStealThreadPool {
|
|
39
|
+
#endif
|
|
40
|
+
public:
|
|
41
|
+
/**
|
|
42
|
+
* 默认构造函数,创建和当前系统CPU数一致的线程数
|
|
43
|
+
*/
|
|
44
|
+
MQStealThreadPool() : MQStealThreadPool(std::thread::hardware_concurrency()) {}
|
|
45
|
+
|
|
46
|
+
/**
|
|
47
|
+
* 构造函数,创建指定数量的线程
|
|
48
|
+
* @param n 指定的线程数
|
|
49
|
+
* @param until_empty 任务队列为空时,自动停止运行
|
|
50
|
+
*/
|
|
51
|
+
explicit MQStealThreadPool(size_t n, bool until_empty = true)
|
|
52
|
+
: m_done(false), m_worker_num(n), m_runnging_until_empty(until_empty) {
|
|
53
|
+
try {
|
|
54
|
+
m_interrupt_flags.resize(m_worker_num);
|
|
55
|
+
for (size_t i = 0; i < m_worker_num; i++) {
|
|
56
|
+
// 创建工作线程及其任务队列
|
|
57
|
+
m_queues.emplace_back(new MQStealQueue<task_type>);
|
|
58
|
+
}
|
|
59
|
+
// 初始完毕所有线程资源后再启动线程
|
|
60
|
+
for (int i = 0; i < m_worker_num; i++) {
|
|
61
|
+
m_threads.emplace_back(&MQStealThreadPool::worker_thread, this, i);
|
|
62
|
+
m_thread_index[m_threads.back().get_id()] = i;
|
|
63
|
+
}
|
|
64
|
+
} catch (...) {
|
|
65
|
+
m_done = true;
|
|
66
|
+
throw;
|
|
67
|
+
}
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
/**
|
|
71
|
+
* 析构函数,等待并阻塞至线程池内所有任务完成
|
|
72
|
+
*/
|
|
73
|
+
~MQStealThreadPool() {
|
|
74
|
+
if (!m_done) {
|
|
75
|
+
join();
|
|
76
|
+
}
|
|
77
|
+
m_threads.clear();
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
/** 获取工作线程数 */
|
|
81
|
+
size_t worker_num() const {
|
|
82
|
+
return m_worker_num;
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
/** 剩余任务数 */
|
|
86
|
+
size_t remain_task_count() const {
|
|
87
|
+
if (m_done) {
|
|
88
|
+
return 0;
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
size_t total = 0;
|
|
92
|
+
for (size_t i = 0; i < m_worker_num; i++) {
|
|
93
|
+
total += m_queues[i]->size();
|
|
94
|
+
}
|
|
95
|
+
return total;
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
/** 先线程池提交任务后返回的对应 future 的类型 */
|
|
99
|
+
template <typename ResultType>
|
|
100
|
+
using task_handle = std::future<ResultType>;
|
|
101
|
+
|
|
102
|
+
#ifdef _MSC_VER
|
|
103
|
+
#pragma warning(push)
|
|
104
|
+
#pragma warning(disable : 4996)
|
|
105
|
+
#endif
|
|
106
|
+
|
|
107
|
+
/** 向线程池提交任务 */
|
|
108
|
+
template <typename FunctionType>
|
|
109
|
+
auto submit(FunctionType f) {
|
|
110
|
+
if (m_done) {
|
|
111
|
+
throw std::logic_error("You can't submit a task to the stopped MQStealThreadPool!");
|
|
112
|
+
}
|
|
113
|
+
|
|
114
|
+
int index = -1;
|
|
115
|
+
auto iter = m_thread_index.find(std::this_thread::get_id());
|
|
116
|
+
if (iter != m_thread_index.end()) {
|
|
117
|
+
index = iter->second;
|
|
118
|
+
}
|
|
119
|
+
|
|
120
|
+
typedef typename std::invoke_result<FunctionType>::type result_type;
|
|
121
|
+
std::packaged_task<result_type()> task(f);
|
|
122
|
+
task_handle<result_type> res(task.get_future());
|
|
123
|
+
|
|
124
|
+
// 如果是本地线程且线程仍未终止,则加入自身队列
|
|
125
|
+
if (index != -1 && m_interrupt_flags[index]) {
|
|
126
|
+
// 本地线程任务从前部入队列(递归成栈)
|
|
127
|
+
m_queues[index]->push_front(std::move(task));
|
|
128
|
+
return res;
|
|
129
|
+
}
|
|
130
|
+
|
|
131
|
+
m_queues[m_current_index]->push(std::move(task));
|
|
132
|
+
m_current_index++;
|
|
133
|
+
if (m_current_index >= m_worker_num) {
|
|
134
|
+
m_current_index = 0;
|
|
135
|
+
}
|
|
136
|
+
return res;
|
|
137
|
+
}
|
|
138
|
+
|
|
139
|
+
#ifdef _MSC_VER
|
|
140
|
+
#pragma warning(pop)
|
|
141
|
+
#endif
|
|
142
|
+
|
|
143
|
+
/** 返回线程池结束状态 */
|
|
144
|
+
bool done() const {
|
|
145
|
+
return m_done;
|
|
146
|
+
}
|
|
147
|
+
|
|
148
|
+
/**
|
|
149
|
+
* 等待各线程完成当前执行的任务后立即结束退出
|
|
150
|
+
*/
|
|
151
|
+
void stop() {
|
|
152
|
+
if (m_done) {
|
|
153
|
+
return;
|
|
154
|
+
}
|
|
155
|
+
|
|
156
|
+
// 同时加入结束任务指示,以便在dll退出时也能够终止
|
|
157
|
+
for (size_t i = 0; i < m_worker_num; i++) {
|
|
158
|
+
if (m_interrupt_flags[i]) {
|
|
159
|
+
m_interrupt_flags[i].set();
|
|
160
|
+
}
|
|
161
|
+
m_queues[i]->push(FuncWrapper());
|
|
162
|
+
}
|
|
163
|
+
|
|
164
|
+
for (size_t i = 0; i < m_worker_num; i++) {
|
|
165
|
+
if (m_threads[i].joinable()) {
|
|
166
|
+
m_threads[i].join();
|
|
167
|
+
}
|
|
168
|
+
}
|
|
169
|
+
|
|
170
|
+
m_done = true;
|
|
171
|
+
for (size_t i = 0; i < m_worker_num; i++) {
|
|
172
|
+
m_queues[i]->clear();
|
|
173
|
+
}
|
|
174
|
+
}
|
|
175
|
+
|
|
176
|
+
/**
|
|
177
|
+
* 等待并阻塞至线程池内所有任务完成
|
|
178
|
+
* @note 至此线程池能工作线程结束不可再使用
|
|
179
|
+
*/
|
|
180
|
+
void join() {
|
|
181
|
+
if (m_done) {
|
|
182
|
+
return;
|
|
183
|
+
}
|
|
184
|
+
|
|
185
|
+
// 指示各工作线程在未获取到工作任务时,停止运行
|
|
186
|
+
if (m_runnging_until_empty) {
|
|
187
|
+
while (true) {
|
|
188
|
+
bool can_quit = true;
|
|
189
|
+
for (size_t i = 0; i < m_worker_num; i++) {
|
|
190
|
+
if (!m_queues[i]->empty()) {
|
|
191
|
+
can_quit = false;
|
|
192
|
+
break;
|
|
193
|
+
}
|
|
194
|
+
}
|
|
195
|
+
|
|
196
|
+
if (can_quit) {
|
|
197
|
+
break;
|
|
198
|
+
}
|
|
199
|
+
|
|
200
|
+
std::this_thread::yield();
|
|
201
|
+
}
|
|
202
|
+
|
|
203
|
+
m_done = true;
|
|
204
|
+
for (size_t i = 0; i < m_worker_num; i++) {
|
|
205
|
+
if (m_interrupt_flags[i]) {
|
|
206
|
+
m_interrupt_flags[i].set();
|
|
207
|
+
}
|
|
208
|
+
}
|
|
209
|
+
}
|
|
210
|
+
|
|
211
|
+
for (size_t i = 0; i < m_worker_num; i++) {
|
|
212
|
+
m_queues[i]->push(FuncWrapper());
|
|
213
|
+
}
|
|
214
|
+
|
|
215
|
+
// 等待线程结束
|
|
216
|
+
for (size_t i = 0; i < m_worker_num; i++) {
|
|
217
|
+
if (m_threads[i].joinable()) {
|
|
218
|
+
m_threads[i].join();
|
|
219
|
+
}
|
|
220
|
+
}
|
|
221
|
+
|
|
222
|
+
m_done = true;
|
|
223
|
+
for (size_t i = 0; i < m_worker_num; i++) {
|
|
224
|
+
m_queues[i]->clear();
|
|
225
|
+
}
|
|
226
|
+
}
|
|
227
|
+
|
|
228
|
+
private:
|
|
229
|
+
typedef FuncWrapper task_type;
|
|
230
|
+
std::atomic_bool m_done; // 线程池全局需终止指示
|
|
231
|
+
size_t m_worker_num; // 工作线程数量
|
|
232
|
+
bool m_runnging_until_empty; // 运行直到队列空时停止
|
|
233
|
+
|
|
234
|
+
std::vector<std::unique_ptr<MQStealQueue<task_type>>> m_queues; // 线程任务队列
|
|
235
|
+
std::vector<InterruptFlag> m_interrupt_flags; // 线程终止标志
|
|
236
|
+
std::vector<std::thread> m_threads; // 工作线程
|
|
237
|
+
|
|
238
|
+
std::unordered_map<std::thread::id, int> m_thread_index;
|
|
239
|
+
int m_current_index = 0; // 当前放置新任务时的队列索引
|
|
240
|
+
|
|
241
|
+
void worker_thread(int index) {
|
|
242
|
+
while (!m_interrupt_flags[index].isSet() && !m_done) {
|
|
243
|
+
run_pending_task(index);
|
|
244
|
+
}
|
|
245
|
+
}
|
|
246
|
+
|
|
247
|
+
void run_pending_task(int index) {
|
|
248
|
+
task_type task;
|
|
249
|
+
// 尝试从本地队列获取任务并执行
|
|
250
|
+
if (m_queues[index]->try_pop(task)) {
|
|
251
|
+
if (task.isNullTask()) {
|
|
252
|
+
m_interrupt_flags[index].set();
|
|
253
|
+
} else {
|
|
254
|
+
task();
|
|
255
|
+
}
|
|
256
|
+
} else if (pop_task_from_other_thread_queue(task, index)) {
|
|
257
|
+
task();
|
|
258
|
+
} else {
|
|
259
|
+
// 阻塞并等待本地队列中有新的任务
|
|
260
|
+
// 注:如果是递归情况,任务被优先加入本地队列且彼此依赖,如果任务被其他线程偷取到的话,将导致其他线程被阻塞并等待
|
|
261
|
+
// 所以,此处等待本地队列而不是继续循环偷取
|
|
262
|
+
m_queues[index]->wait_and_pop(task);
|
|
263
|
+
if (task.isNullTask()) {
|
|
264
|
+
m_interrupt_flags[index].set();
|
|
265
|
+
} else {
|
|
266
|
+
task();
|
|
267
|
+
}
|
|
268
|
+
}
|
|
269
|
+
}
|
|
270
|
+
|
|
271
|
+
bool pop_task_from_other_thread_queue(task_type& task, int index) {
|
|
272
|
+
for (size_t i = 0; i < m_worker_num; ++i) {
|
|
273
|
+
size_t pos = (index + i + 1) % m_worker_num;
|
|
274
|
+
if (pos != index && m_queues[pos]->try_steal(task)) {
|
|
275
|
+
return true;
|
|
276
|
+
}
|
|
277
|
+
}
|
|
278
|
+
return false;
|
|
279
|
+
}
|
|
280
|
+
}; // namespace hku
|
|
281
|
+
|
|
282
|
+
} /* namespace hku */
|
|
283
|
+
|
|
284
|
+
#ifdef __GNUC__
|
|
285
|
+
#pragma GCC diagnostic pop
|
|
286
|
+
#endif
|