|
从reddit/hackernews/lobsters/meetingcpp知乎等等摘抄一些c++动态
周刊项目地址|在线地址 |知乎专栏 |腾讯云+社区
弄了个qq频道,手机qq点击进入
欢迎投稿,推荐或自荐文章/软件/资源等
可以贴在下一期草稿里 草稿链接
2022 0916
<hr/>资讯
标准委员会动态/ide/编译器信息放在这里
编译器信息最新动态推荐关注hellogcc公众号 2022-09-14 第167期
cppcon 2022还在进行中。视频放了几个。没看。有参与者说今年不太行。我去年还没怎么看。看视频信息量太低了。得看PPT然后找视频看。最近没啥空。周末有时间可以看看
文章
- Did you know that C++23 added stacktrace library?
打印堆栈支持。看代码
#include <stacktrace>
#include <iostream>
int foo() {
std::cout << std::stacktrace::current();
return {};
}
int main() {
return foo();
}
可算支持了 - C++20 Modules Status Report
各个编译器Modules支持的状态进展介绍
- The Case for std::optional of Reference Types and Void
标准库的std::optional是不支持T&和void的。作者说了下自己可能会用到这个场景,标准库应该加上
- Use-after-freedom: MiraclePtr
- Pointer Safety Ideas
之前介绍过。介绍了谷歌浏览器团队在解决指针问题的一些实践。实现了很多,但是有些文档不可见。
也介绍了其他方案的实现,比如这个unowned_ptr
代码难找就没有深入研究。不过讨论还是值得一看的。我后面整理一下
- 如何高效解决 C++内存问题,Apache Doris 实践之路|技术解析
介绍Sanitizer
- 用户态操作系统之七 Seastar的文件操作
- 用户态操作系统之八 Seastar的coroutine支持
seastar代码走读
注意co_await的阻塞语义,永远超时导致不能使用
四舍五入等于c的东西。可以看个热闹
- Non-standard containers in C++
各种容器介绍,比如folly::fbvector, boost::small_vector等等。感兴趣的可以看看
- GCC Translation Validation
写了个工具验证gcc产出的代码对不对,具体就是验证gimple IR。我不太懂。感兴趣可以看看
- Integrating C++ header units into Office using MSVC (1/n)
office团队要用module,这是msvc团队的一些探索
- Is there any meaningful way to compare two Time Travel Debugging positions?
介绍msvc调试的。没用过不了解,有没有懂的给讲讲
- The case of the recursively-acquired non-recursive lock, and how to avoid the unintentional reentrancy
代码长这样
struct WidgetTracker : IWidgetChangeNotificationSink
{
/* other stuff not relevant here */
/// IWidgetChangeNotificationSink
STDMETHODIMP OnCurrentWidgetChanged();
private:
WRL::ComPtr<IWidget> m_currentWidget;
std::mutex m_mutex;
};
HRESULT WidgetTracker::OnCurrentWidgetChanged()
{
auto guard = std::lock_guard(m_mutex);
RETURN_IF_FAILED(GetCurrentWidget(&m_currentWidget));
return S_OK;
}
OnCurrentWidgetChanged是个回调,如果m_currentWidget变了就会被调用
问题在于OnCurrentWidgetChanged被调用这个m_mutex锁住的瞬间,m_currentWidget析构,结果又触发一次OnCurrentWidgetChanged,导致死锁
这个问题根源在于锁锁不住comptr,无法避免递归调用。
解决方法也很简单,拷贝一份对象就行了。
HRESULT WidgetTracker::OnCurrentWidgetChanged()
{
WRL::ComPtr<IWidget> widget; // 可能别人在用它
auto guard = std::lock_guard(m_mutex);
RETURN_IF_FAILED(GetCurrentWidget(&widget));
m_currentWidget.Swap(widget);
return S_OK;
}
作者之前讨论过一段类似的代码,用的,shared_ptr, 也有相同的问题
class ThingManager
{
private:
std::mutex things_lock_;
std::vector<std::shared_ptr<Thing>> things_;
public:
void AddThing(std::shared_ptr<Thing> thing)
{
std::lock_guard guard(things_lock_);
things_.push_back(std::move(thing));
}
void RemoveThingById(int32_t id)
{
std::lock_guard guard(things_lock_);
auto it = std::find_if(things_.begin(), things_.end(),
[&](auto&& thing)
{
return thing->id() == id;
});
if (it != things_.end()) {
things_.erase(it);
}
}
};
class SuperThing : Thing
{
private:
ThingManager& manager_;
int32_t helper_id_ = 0;
public:
SuperThing(ThingManager& manager) :
manager_(manager)
{
auto helper = std::make_shared<Thing>();
helper_id_ = helper->id();
manager_.AddThing(helper);
}
~SuperThing()
{
manager_.RemoveThingById(helper_id_);
}
};
void test(ThingManager& manager)
{
auto s = std::make_shared<SuperThing>(manager);
auto id = s->id();
manager.AddThing(s);
s = nullptr; // 1
manager.RemoveThingById(id); // 2
}
问题是相同的,同一个锁被锁两次。如何触发?首先SuperThing会在2 这行真正的析构,1那行只会引用计数-1 RemoveThingById(id)是会锁的,内部触发了SuperThing析构,然后又调用了manager_.RemoveThingById(helper_id_);,锁了同一个锁
你可能觉得这种代码写的有问题。这是锁和shared_ptr和坑爹析构三个同时引入引发的问题,我遇不到
解决方法也很简单。让这个shared_ptr活着,因为不知道哪个外部调用会用到这个shared_ptr
void RemoveThingById(int32_t id)
{
std::shared_ptr removed_thing; // 求求你活着
{
std::lock_guard guard(things_lock_);
auto it = std::find_if(things_.begin(), things_.end(), ...);
if (it != things_.end()) {
removed_thing = *it;
things_.erase(it);
}
}
}
引用计数指针和锁的问题。这里打个问号。要注意
oldnewthing的博客真精彩,总能遇到各种莫名其妙的bug
- Integer Conversions and Safe Comparisons in C++20
标准库提供了新函数来更友好的判断整数大小,不用自己写那些符号转换逻辑了
比如
template <class _Ty1, class _Ty2>
_NODISCARD constexpr bool cmp_equal(const _Ty1 _Left, const _Ty2 _Right) noexcept {
static_assert(_Is_standard_integer<_Ty1> && _Is_standard_integer<_Ty2>,
&#34;The integer comparison functions only &#34;
&#34;accept standard and extended integer types.&#34;);
if constexpr (is_signed_v<_Ty1> == is_signed_v<_Ty2>) {
return _Left == _Right;
} else if constexpr (is_signed_v<_Ty2>) {
return _Left == static_cast<make_unsigned_t<_Ty2>>(_Right) && _Right >= 0;
} else {
return static_cast<make_unsigned_t<_Ty1>>(_Left) == _Right && _Left >= 0;
}
}
- Unsigned comparisons in AVX2/SSE: a quick note
VPSUBUSB z, x, y
VPMINUB z, x, y
VPCMPEQB w, z, x我不太懂。不评价
- Escaping strings faster with AVX-512
用avx处理字符串中的斜杠,比如my title is \&#34;La vie\&#34;
通常写法
for (...) {
if ((*in == &#39;\\&#39;) || (*in == &#39;&#34;&#39;)) {
*out++ = &#39;\\&#39;;
}
*out++ = *in;
}
sse/avx写法
__m512i solidus = _mm512_set1_epi8(&#39;\\&#39;);
__m512i quote = _mm512_set1_epi8(&#39;&#34;&#39;);
for (; in + 32 <= finalin; in += 32) {
__m256i input = _mm256_loadu_si256(in);
__m512i input1 = _mm512_cvtepu8_epi16(input);
__mmask64 is_solidus = _mm512_cmpeq_epi8_mask(input1, solidus);
__mmask64 is_quote = _mm512_cmpeq_epi8_mask(input1, quote);
__mmask64 is_quote_or_solidus = _kor_mask64(is_solidus, is_quote);
__mmask64 to_keep = _kor_mask64(is_quote_or_solidus, 0xaaaaaaaaaaaaaaaa);
__m512i shifted_input1 = _mm512_bslli_epi128(input1, 1);
__m512i escaped =
_mm512_mask_blend_epi8(is_quote_or_solidus, shifted_input1, solidus);
_mm512_mask_compressstoreu_epi8(out, to_keep, escaped);
out += _mm_popcnt_u64(_cvtmask64_u64(to_keep));
}
给我看困了
这里有个类似的https://branchfree.org/2019/03/06/code-fragment-finding-quote-pairs-with-carry-less-multiply-pclmulqdq/
- The case of the APC that never arrives
这段代码有bug,不懂这几个API的可能看不懂
bool ShuttingDown = false;
void MainThread()
{
DWORD id;
auto hThread = CreateThread(nullptr, 0, WorkerThread,
nullptr, 0, &id); // succeeds
BlahBlahBlah(); // do useful work
// Time to clean up. Post an APC to the worker thread
// to tell it that it&#39;s time to go home.
QueueUserAPC(WakeWorker, hThread, 0); // succeeds
WaitForSingleObject(hThread, INFINITE); // hangs
CloseHandle(hThread);
}
void CALLBACK WakeWorker(ULONG_PTR)
{
ShuttingDown = true;
}
DWORD CALLBACK WorkerThread(void*)
{
// Do work until shut down.
do
{
// All work is posted via APCs.
SleepEx(INFINITE, TRUE);
} while (!ShuttingDown);
return 0;
}
简单来说SleepEx通过QueueUserAPC来唤醒,有一种场景,QueueUserAPC唤醒了,但是CreateThread执行的慢,导致SleepEx没收到通知,从而永远死锁
怎么解决这个问题?把do while循环改成while就行了。因为这种场景已经shutdown了,不应该执行sleep
DWORD CALLBACK WorkerThread(void*)
{
// Do work until shut down.
while (!ShuttingDown)
{
// All work is posted via APCs.
SleepEx(INFINITE, TRUE);
}
return 0;
}
- Serializing asynchronous operations in C++/WinRT
- Creating a manual-start C++/WinRT coroutine from an eager-start one, part 1
- Creating a lazy-start C++/WinRT coroutine from an eager-start one, part 2
讲协程的。说来惭愧我还不是很懂。就不介绍了
视频
- C++ Weekly - Ep 341 - std format vs lib {fmt}
简单来说只有clang编译器支持std::format
开源项目需要人手
- asteria 一个脚本语言,可嵌入,长期找人,希望胖友们帮帮忙,也可以加群384042845和作者对线
- pika 一个nosql 存储, redis over rocksdb,非常需要人贡献代码胖友们, 感兴趣的欢迎加群294254078前来对线
新项目介绍/版本更新
- less 一个vector实现
- alpaca 一个编码库
工作招聘
寒冬了。保佑我不被开
看到这里或许你有建议或者疑问或者指出错误,请留言评论! 多谢! 你的评论非常重要!也可以帮忙点赞收藏转发!多谢支持!
本文永久链接 |
|