周刊项目地址[1]
RSS https://github.com/wanghenshui/cppweeklynews/releases.atom
欢迎投稿,推荐或自荐文章/软件/资源等
请提交 issue[3]
最近在找工作准备面试题,更新可能有些拖沓,见谅
本周内容比较少
本期文章由 Amnesia Captain 黄亮 Anein Jerry 赞助
资讯
标准委员会动态/ide/编译器信息放在这里
编译器信息最新动态推荐关注hellogcc公众号 OSDT Weekly 2023-11-22 第229期
boost 有个scope库正在评审中 https://lastique.github.io/scope/libs/scope/doc/html/scope/scope_guards.html
简单来说又是个scope guard
文章
- • A Concise Introduction to Coroutines by Dian-Lun Lin[4]
还是coroutine介绍。懂得可以跳过了
代码语言:javascript复制#include <coroutine>
#include <iostream>
struct MyCoroutine { // (1)
struct promise_type {
MyCoroutine get_return_object() {
return std::coroutine_handle<promise_type>::from_promise(*this);
}
std::suspend_always initial_suspend() {
return {};
}
std::suspend_always final_suspend() noexcept {
return {};
}
void return_void() {}
void unhandled_exception() {}
};
MyCoroutine(std::coroutine_handle<promise_type> handle): handle{handle} {}
void resume() {
handle.resume();
}
void destroy() {
handle.destroy();
}
std::coroutine_handle<promise_type> handle;
};
MyCoroutine simpleCoroutine() { // (2)
std::cout << "Start coroutinen";
co_await std::suspend_always{};
std::cout << "Resume coroutinen";
}
int main() {
MyCoroutine coro = simpleCoroutine();
std::cout << "Coroutine is not executed yetn";
coro.resume();
std::cout << "Suspend coroutinen";
coro.resume();
coro.destroy();
return 0;
}
实际上是这样的,注意对应关系。还是比较简单的
代码语言:javascript复制MyCoroutine simpleCoroutine() {
MyCoroutine::promise_type p();
MyCoroutine coro_obj = p.get_return_object();
try {
co_await p.inital_suspend();
std::cout << "Start coroutinen";
co_await std::suspend_always{};
std::cout << "Resume coroutinen";
} catch(...) {
p.unhandled_exception();
}
co_await p.final_suspend();
}
代码语言:javascript复制
理解Awaitable,suspend_always就是内建的一个简单awaitable
代码语言:javascript复制struct suspend_always {
constexpr bool await_ready() const noexcept { return false; }
constexpr void await_suspend(coroutine_handle<>) const noexcept {}
constexpr void await_resume() const noexcept {}
};
代码语言:javascript复制
co_await suspend_always 相当于
代码语言:javascript复制auto&& awaiter = std::suspend_always{};
if(!awaiter.await_ready()) {
awaiter.await_suspend(std::coroutine_handle<>...);
//<suspend/resume>
}
awaiter.await_resume();
代码语言:javascript复制
这样最重要的co_await功能大概你就明白了
好了,来点复杂的
代码语言:javascript复制#include <coroutine>
#include <iostream>
#include <queue>
struct Task {
struct promise_type {
std::suspend_always initial_suspend() noexcept { return {}; }
std::suspend_always final_suspend() noexcept { return {}; }
Task get_return_object() {
return std::coroutine_handle<promise_type>::from_promise(*this);
}
void return_void() {}
void unhandled_exception() {}
};
Task(std::coroutine_handle<promise_type> handle): handle{handle} {}
auto get_handle() { return handle; }
std::coroutine_handle<promise_type> handle;
};
class Scheduler {
std::queue<std::coroutine_handle<>> _tasks;
public:
void emplace(std::coroutine_handle<> task) {
_tasks.push(task);
}
void schedule() {
while(!_tasks.empty()) {
auto task = _tasks.front();
_tasks.pop();
task.resume();
if(!task.done()) {
_tasks.push(task);
}
else {
task.destroy();
}
}
}
auto suspend() {
return std::suspend_always{};
}
};
Task TaskA(Scheduler& sch) {
std::cout << "Hello from TaskAn";
co_await sch.suspend();
std::cout << "Executing the TaskAn";
co_await sch.suspend();
std::cout << "TaskA is finishedn";
}
Task TaskB(Scheduler& sch) {
std::cout << "Hello from TaskBn";
co_await sch.suspend();
std::cout << "Executing the TaskBn";
co_await sch.suspend();
std::cout << "TaskB is finishedn";
}
int main() {
std::cout << 'n';
Scheduler sch;
sch.emplace(TaskA(sch).get_handle());
sch.emplace(TaskB(sch).get_handle());
std::cout << "Start scheduling...n";
sch.schedule();
std::cout << 'n';
}
可以了。你已经入门了。接下来可以看seastar代码了
或者先看这个 https://github.com/andreasbuhr/cppcoro
- • Formatting Custom types with std::format from C 20[5]
简单玩法
代码语言:javascript复制struct Color {
uint8_t r{ 0 };
uint8_t g{ 0 };
uint8_t b{ 0 };
};
template <>
struct std::formatter<Color> {
constexpr auto parse(std::format_parse_context& ctx) {
return ctx.begin();
}
auto format(const Color& col, std::format_context& ctx) const {
return std::format_to(ctx.out(), "({}, {}, {})", col.r, col.g, col.b);
}
};
恐怖玩法
代码语言:javascript复制template <>
struct std::formatter<Color> : std::formatter<string_view> {
auto format(const Color& col, std::format_context& ctx) const {
std::string temp;
std::format_to(std::back_inserter(temp), "({}, {}, {})",
col.r, col.g, col.b);
return std::formatter<string_view>::format(temp, ctx);
}
};
满头大汗玩法
代码语言:javascript复制template <>
struct std::formatter<Color> {
constexpr auto parse(std::format_parse_context& ctx){
auto pos = ctx.begin();
while (pos != ctx.end() && *pos != '}') {
if (*pos == 'h' || *pos == 'H')
isHex_ = true;
pos;
}
return pos; // expect `}` at this position, otherwise,
// it's error! exception!
}
auto format(const Color& col, std::format_context& ctx) const {
if (isHex_) {
uint32_t val = col.r << 16 | col.g << 8 | col.b;
return std::format_to(ctx.out(), "#{:x}", val);
}
return std::format_to(ctx.out(), "({}, {}, {})", col.r, col.g, col.b);
}
bool isHex_{ false };
};
// std::cout << std::format("col {}n", Color{ 100, 200, 255 });
// std::cout << std::format("col {:h}n", Color{ 100, 200, 255 });
// col (100, 200, 255)
// col #64c8ff
- • C needs undefined behavior, but maybe less[6]
c 和编译器结合太深了。但有些知识并不是都知道,导致错误触发未定义行为
- • 现代C 性能优化[7]
这个基本上是去年cppcon的总结,挺好的。值得看看,基本名词都点到了
- • C 20使用pfr库遍历[8]
这个pfr magic_get希望大家都掌握。起码嘴了十几次了
- • 基于 Glibc 版本升级的 DolphinDB 数据查询性能优化实践[9]
patchelf实践还是比较少见的。挺有意思
- • Struct initialization[10]
#include <iostream>
#include <string>
struct S {
int m_num;
std::string m_text;
};
int main() {
S s{42};
std::cout << "s.m_num: " << s.m_num << ", s.m_text: " << s.m_text << 'n';
}
这种构造有字段没初始化,加告警-Wmissing-field-initializers
开源项目介绍
- • asteria[11] 一个脚本语言,可嵌入,长期找人,希望胖友们帮帮忙,也可以加群384042845和作者对线
最近进展,发现自旋竟然比metux还慢,还在研究,改掉原子锁性能提升明显
感觉和业务相关
- • Unilang[12] deepin的一个通用编程语言,点子有点意思,也缺人,感兴趣的可以github讨论区或者deepin论坛看一看。这里也挂着长期推荐了
- • https://gitee.com/okstar-org/ok-edu-desktop 一个IM通信软件,做IM的可以关注,现在正在做全面整合阶段,开始组建商业团队阶段,年底开始融资,你参加了就快发财了,会的快来
- • https://github.com/sharkdp/minicpp 基于inotify的一个repl c 环境
简单说就是你的文件更改了 触发inotify 然后 回调一下make
这可比cling简单多了
- • https://github.com/batterycenter/embed
又一个embed库。std::embed还没影呢,凑活用的东西
- • https://github.com/stephenberry/glaze
很快,但没有和sonic-cpp的对比。我本来想比一下
我折腾了半天sonic-cpp编译。ubuntu 2204 zen4. 各种编不过。放弃了我靠
跑了glaze自带的压测
比yyjson快。性能不错,和simdjson也有一拼。另外就是还用上了最新反射技术。实践挺深的
数据贴这里[13],感兴趣的自己看吧
招聘
无锡编译期HPC AI创业 需要会LLVM gcc的 https://mp.weixin.qq.com/s/qkwjICB_fzzMJErXmbKBBw
互动环节
哎,再也不喝冰美式。一宿没睡着我靠,发现楼下凌晨一点炒米粉,离谱
之前收集了一波读者投票,关于周更其余实践插一些别的内容
能看到大家投票的重点在代码介绍代码走读。这里搞点素材给大家逼逼两句。类似lighting talk,5页10页ppt
另外也收集收集大家的其他意见以及投稿。能投稿广告收益都给你。咱们公众号每篇文章稳定收益7块,加个鸡腿没啥问题
本周内容不多啊,还是希望大家多多互动
引用链接
[1]
周刊项目地址: https://github.com/wanghenshui/cppweeklynews
[2]
手机qq点击进入: https://qm.qq.com/q/6NGizNPyG4
[3]
提交 issue: https://github.com/wanghenshui/cppweeklynews/issues
[4]
A Concise Introduction to Coroutines by Dian-Lun Lin: https://www.modernescpp.com/index.php/a-concise-introduction-to-coroutines-by-dian-lun-li/
[5]
Formatting Custom types with std::format from C 20: https://www.cppstories.com/2022/custom-stdformat-cpp20/
[6]
C needs undefined behavior, but maybe less: https://www.think-cell.com/en/career/devblog/cpp-needs-undefined-behavior-but-maybe-less
[7]
现代C 性能优化: https://zhuanlan.zhihu.com/p/663843832
[8]
C 20使用pfr库遍历: https://zhuanlan.zhihu.com/p/668536219
[9]
基于 Glibc 版本升级的 DolphinDB 数据查询性能优化实践: https://zhuanlan.zhihu.com/p/667724630
[10]
Struct initialization: https://www.sandordargo.com/blog/2023/11/22/struct-initialization
[11]
asteria: https://github.com/lhmouse/asteria
[12]
Unilang: https://github.com/linuxdeepin/unilang
[13]
数据贴这里: https://github.com/wanghenshui/wanghenshui.github.io/issues/97