c++ - 重塑微软的 Concurrency::diagnostic::span 也可以检测外跨度
问题描述
我希望创建ScopePrinter
与Microsoft 类似的 Concurrency::diagnostic::span
工作,
但它也可以检测封装范围。
ScopePrint sc2{"scope1"}; // should print "[start scope1]"
createTask([&](){
ScopePrint sc2{"scope2"}; // should print "[start scope1/scope2]"
//do something expensive (can create more tasks & ScopePrints)
// should print "[end scope1/scope2]"
});
// should print "[end scope1]"
这是我的MCVE。
fib()
并且fibPrint()
只是一个昂贵的虚拟功能。
ScopePrinter(X)
[begin X]
是我在构造函数处打印并[end X]
在其块结束时 打印的实用程序。
int fib(int n) { // just something that burn some CPU cycles
if (n<2) return n;
return fib(n-1) + fib(n-2);
}
void fibPrint(int n) { // just something that burn some CPU cycles
std::cout<<n<<" fib= "<<fib(n)<<std::endl;
}
struct ScopePrinter{ // my Utility class - useful for profiling
std::string name="";
public: ScopePrinter(std::string strP){
name=strP; std::cout<< ("[start "+name +"]\n");
//in real case, it cache current time too
}
public: ~ScopePrinter(){
std::cout<< ("[end "+name +"]\n");
//in real case, it prints total used time too
}
};
这是main()
:-
int main() {
auto a1 = std::async([&](){
ScopePrinter s("a1");
fibPrint(5);
} );
auto a2 = std::async([&](){
ScopePrinter s("a2");
fibPrint(6);
} );
auto a3 = std::async([&](){
ScopePrinter s("a3");
fibPrint(7);
{
auto a31 = std::async([&](){
ScopePrinter s("a31");
fibPrint(8);
} );
auto a32 = std::async([&](){
ScopePrinter s("a32");
fibPrint(9);
} );
}
} );
a1.wait();
}
这是一个可能的输出:-
[start a1]
[start a2]
5 fib= 6 fib= 58
[end a1]
[end a2]
[start a3]
7 fib= 13
[start a31]
8 fib= 21
[end a31]
[start a32]
9 fib= 34
[end a32]
[end a3]
如何使ScopePrinter("a31")
构造函数和析构函数打印完整范围,例如[start a3/a31]
and[end a3/a31]
而不是[start a31]
and [end a31]
?
这对于分析我的多线程程序非常有用。
我正在考虑thread_local
和 MACRO,但我认为这不会有帮助。
解决方案
如果您希望a3/a31
并a3/a32
显示为子范围,那么您只需将指针传递给外部范围,并使用它来构建一个复合名称:
struct ScopePrinter {
std::string name;
public:
ScopePrinter(std::string strP, ScopePrinter* parent = nullptr)
: name((parent ? parent->name + "/" : "") + strP) {
std::cout << ("[start " + name + "]\n");
}
public:
~ScopePrinter() { std::cout << ("[end " + name + "]\n"); }
};
然后在嵌套调用的情况下,您可以传入外部范围:
auto a3 = std::async([&]() {
ScopePrinter s("a3");
fibPrint(7);
{
auto a31 = std::async([&]() {
ScopePrinter s1("a31", &s);
fibPrint(8);
});
auto a32 = std::async([&]() {
ScopePrinter s2("a32", &s);
fibPrint(9);
});
}
});
这将打印如下内容:
[start a1]
5 fib= 5
[end a1]
[start a3]
7 fib= [start a2]
6 fib= 138
[end a2]
[start a3/a31]
8 fib= [start a3/a32]
9 fib= 34
[end a3/a32]
21
[end a3/a31]
[end a3]
推荐阅读
- python - 无法从内部获取文本/数据使用 BeautifulSoup
- python-3.x - 在 minmaxscalar 期间超出最大递归深度
- python - TypeError: 不支持的操作数类型 -: 'generator' 和 'NoneType'
- docker - /bin/sh 返回非零代码:docker alpine 中的 1
- php - Ninja Forms 动作的顺序可以更改吗?
- ios - 有没有办法知道广告设备是安卓还是ios?
- excel - 如何循环 VBA 代码以运行每个列值(20,000 多个单元格)而不使其变慢
- mongodb - 点和美元符号的mongodb含义
- c# - 我正在寻找“滑动阵列”
- google-cloud-platform - 如何从 Catalog API 获取 GCP 定价列表