我有一个基于tokio的单线程异步应用程序,其中使用Arcs 或其他Sync类型似乎是一种开销。因为线程之间不需要同步,所以我正在寻找类似tokio::sync::oneshot::channel 的东西,Sender并且Receiver它应该!Sync并且可以被包装到Rc而不是Arc.
Rust 中是否有专门设计的同步原语可用于单线程异步应用程序?
最近我发现不知什么原因std::this_thread::sleep_for可以比预期的睡眠时间长 10 倍。这不仅仅是一个或几个偶然的延迟,而是非常显着的效果,可以持续几分钟,并且还会影响std::condition_variable::wait_for。
这是我的代码:
#include <thread>
#include <iostream>
#include <chrono>
using namespace std;
int main(int argc, char const *argv[])
{
unsigned t = 0;
auto start = ::std::chrono::steady_clock::now();
for(unsigned i = 0; i < 100; ++i) {
::std::this_thread::sleep_for(chrono::milliseconds(1));
t ^= i; // prevent overeager optimization
}
auto stop = ::std::chrono::steady_clock::now();
auto elapsed = ::std::chrono::duration_cast<::std::chrono::milliseconds>(stop - start);
::std::cout << elapsed.count() << "\n";
::std::cerr << t << "\n";
return 0;
}
Run Code Online (Sandbox Code Playgroud)
我用 Visual Studio 命令行工具编译了这个,如下所示:
cl /EHsc /std:c++17 …Run Code Online (Sandbox Code Playgroud) 我正在测试自定义删除器unique_ptr.奇怪的是,只有作为功能对象的删除工作正常.如果我用函数或lambdas替换它们,程序不会编译.我究竟做错了什么?
这是我完整的测试程序
#include <iostream>
#include <memory>
using namespace std;
class Vehicle {
public:
Vehicle(){ cout<<"Vehicle constructor..."<<endl;}
virtual ~Vehicle(){cout<<"~Vehicle destructor..."<<endl;}
virtual void go()=0;
};
class Car:public Vehicle {
public:
void go() override {
cout<<"Going by car..."<<endl;
}
};
class Bicycle:public Vehicle {
public:
void go() override {
cout<<"Going by bicycle..."<<endl;
}
};
// Custom deleters
auto CustomLambdaDeleter = [](Vehicle* v){
cout<<"Custom lambda deleter called..."<<endl;
delete v;
};
void CustomFunctionDeleter(Vehicle* v){
cout<<"Custom function deleter called..."<<endl;
delete v;
}
struct CustomFunctorDeleter …Run Code Online (Sandbox Code Playgroud) 我有一个在 STM32f103C8 上运行的简单闪烁 LED 程序(没有初始化样板):
void soft_delay(void) {
for (volatile uint32_t i=0; i<2000000; ++i) { }
}
uint32_t iters = 0;
while (1)
{
LL_GPIO_TogglePin(LED_GPIO_Port, LED_Pin);
soft_delay();
++iters;
}
Run Code Online (Sandbox Code Playgroud)
它是用Keil uVision v.5(默认编译器)和CLionusingarm-none-eabi-gcc编译器编译的。令人惊讶的是,arm-none-eabi-gcc 程序在发布模式 (-O2 -flto) 下运行速度慢 50%,在调试模式下运行速度慢 100%。
我怀疑有3个原因:
Keil过度优化(不太可能,因为代码很简单)
由于错误的编译器标志,arm-none-eabi-gcc 优化不足(我使用 CLion Embedded 插件`CMakeLists.txt)
初始化中的一个错误,导致芯片在使用arm-none-eabi-gcc时具有较低的时钟频率(待调查)
我还没有深入到优化和反汇编的丛林中,我希望有许多经验丰富的嵌入式开发人员已经遇到过这个问题并有答案。
更新1
通过尝试 Keil ArmCC 的不同优化级别,我了解了它如何影响生成的代码。它影响很大,尤其是执行时间。soft_delay()以下是每个优化级别的基准测试和函数反汇编(RAM 和 Flash 数量包括初始化代码)。
-O0:RAM:1032,闪存:1444,执行时间(20 次迭代):18.7 秒
soft_delay PROC
PUSH {r3,lr}
MOVS r0,#0
STR r0,[sp,#0]
B |L6.14|
|L6.8|
LDR r0,[sp,#0]
ADDS …Run Code Online (Sandbox Code Playgroud) 当您想使用 g++ 静态链接所有可用库时,此人会将-static标志传递给编译器。
但是如何从 Qt Creator 做到这一点呢?
首先,我尝试了这个建议: 如何使 Qt 和 Qtcreator 静态而不是动态链接库?
该帖子建议使用
CONFIG += static
Run Code Online (Sandbox Code Playgroud)
但这根本行不通。
其次,我尝试了另一种方法并将以下行添加到我的 .pro 文件中:
QMAKE_CXXFLAGS += -static
Run Code Online (Sandbox Code Playgroud)
那也没有解决问题。我分析了编译器输出并发现:
-static 标志仅在将源编译为目标文件时添加。但是在构建可执行文件时,此标志不存在。
以下是我从编译器输出选项卡复制的确切编译器命令:
g++ -c -pipe -fno-keep-inline-dllexport -static -g -std=gnu++11 -frtti -Wall -Wextra -fexceptions -mthreads -DUNICODE -DQT_QML_DEBUG -I..\..\..\ASSETS\PROG_CPP\MY_CPP\2016\test -I. -I..\..\..\icu\dist\include -I..\..\5.7\mingw53_32\mkspecs\win32-g++ -o debug\main.o ..\..\..\ASSETS\PROG_CPP\MY_CPP\2016\test\main.cpp
g++ -Wl,-subsystem,console -mthreads -o debug\test.exe debug/main.o -LC:\icu\dist\lib -lsicuio -lsicuin -lsiculx -lsicule -lsicuuc C:\icu\dist\lib\sicudt.a -lpthread -lm
Run Code Online (Sandbox Code Playgroud)
如何强制 Qmake 将 -static 添加到所有命令?
c++ ×3
arm ×1
asynchronous ×1
c ×1
c++11 ×1
gcc ×1
lambda ×1
qmake ×1
qt-creator ×1
rust ×1
rust-tokio ×1
stm32 ×1
unique-ptr ×1