如何只执行一段代码一次
How to execute a piece of code only once?
我有一个应用程序,其中有几个功能。每个函数都可以根据用户输入被调用多次。然而,我需要在函数中执行一小段代码,只有一次,最初是在启动应用程序时。当在稍后的时间点再次调用同一函数时,必须不执行这段特定的代码。代码在 vc++ 中。请告诉我处理这件事最有效的方法。
使用lambda函数的精简版:
void foo()
{
static bool once = [](){
cout << "once" << endl;
return true;
} ();
cout << "foo" << endl;
}
lambda函数中的代码只执行一次,当静态变量初始化为lambda函数的返回值时。只要编译器支持线程安全的静态初始化,它就应该是线程安全的。
使用c++ 11——使用std::call_once
#include <mutex>
std::once_flag onceFlag;
{
....
std::call_once ( onceFlag, [ ]{ /* my code body here runs only once */ } );
....
}
使用全局静态对象与构造函数(在main
之前调用)?或者只是在一个例程中
static bool initialized;
if (!initialized) {
initialized = true;
// do the initialization part
}
在很少的情况下,这还不够快!
附录
在多线程上下文中,这可能不够:
您可能还对GCC的pthread_once或 constructor
函数__attribute__
感兴趣。
在c++ 11中,您可能需要std::call_once.
如果你的函数可以从多个线程调用,你可能想使用<atomic>
,也许声明static volatile std::atomic_bool initialized;
(但你需要小心)。
但是这些可能在您的系统上不可用;它们在Linux上是可用的!
可以使用本地静态变量:
void foo()
{
static bool wasExecuted = false;
if (wasExecuted)
return;
wasExecuted = true;
...
}
除了@Basile的答案之外,您还可以使用lambda封装静态变量,如下所示:
if ([] {
static bool is_first_time = true;
auto was_first_time = is_first_time;
is_first_time = false;
return was_first_time; } ())
{
// do the initialization part
}
这使得它很容易转换为通用宏:
#define FIRST_TIME_HERE ([] {
static bool is_first_time = true;
auto was_first_time = is_first_time;
is_first_time = false;
return was_first_time; } ())
可以放置在你想要呼叫的任何地方:
if (FIRST_TIME_HERE) {
// do the initialization part
}
为了更好地测量,原子缩短表达式,使其线程安全:
#include <atomic>
#define FIRST_TIME_HERE ([] {
static std::atomic<bool> first_time(true);
return first_time.exchange(false); } ())
你可以这样做吗
有一个返回bool值或某种数据类型的函数init
我这样做了,你需要静态bool来实现
bool init()
{
cout << "Once " <<endl;
return true||false;// value isn't matter
}
void functionCall()
{
static bool somebool = init(); // this line get executed once
cout << "process " <<endl;
}
int main(int argc, char *argv[])
{
functionCall();
functionCall();
functionCall();
return EXIT_SUCCESS;
}
对C #include <stdio.h>
void init()
{
printf("initn");
}
void process()
{
static int someint = 0;
if(someint == 0)
{
someint = 1;
init();
}
printf("processn");
}
int main()
{
process();
process();
process();
return 0;
}
std::call_once()
等。如果您不需要完全线程安全的解决方案,可能是多余的。
如果没有,我们可以使用c++ 17的初始化-within- if
和std::exchange()
:
#include <utility>
void
do_something_expensive_once()
{
if ( static auto called = false; !std::exchange(called, true) ) {
do_something_expensive();
}
}
如果这是一个你经常使用的模式,那么我们可以通过一个标签类型来封装它:
#include <iostream>
#include <utility>
template <typename T>
auto
call_once()
{
static auto called = false;
return !std::exchange(called, true);
}
void
do_something_expensive()
{
std::cout << "something expensiven";
}
void
do_something_expensive_once()
{
if ( call_once<struct TagForSomethingExpensive>() ) {
do_something_expensive();
}
}
auto
main() -> int
{
for (auto i = 0; i < 5; ++i) {
do_something_expensive_once();
}
return 0;
}
这将只打印something expensive
一次。结果!它还使用了在模板参数列表中声明标记struct
的功能,以最大限度地简化。
或者,你可以模板一个函数的地址,一个唯一的整数,等等。
您还可以将一个可调用对象传递给call_once()
,等等。一如既往的c++:可能性是无限的!
考虑到std::call_once()
和通常关于线程安全的警告,这里有另一个轻量级选项,它可以避免未使用的变量警告,并使我们的标志保持在块范围内:
for (static bool once=true; once; once=false) {
yourCodeHere();
}
do {
//execute code once
} while (false)
- 谷歌基准测试,如何只调用一次代码?
- 代码执行/CPU 速度每 2 秒减慢一次
- 代码只输出一次 std::vector,而不是多次输出
- 我如何使一行代码可以选择,但在已经选择过一次后不重新选择
- 循环在此代码中仅迭代一次,而在另一个代码中正确迭代
- Qt C++每秒运行一次代码
- 如何将.txt文件中的多维数组放入代码中,并一次打印一行
- 代码无限循环不能只打印一次
- 限制C++更新速率.为什么此代码每秒更新一次,而不是每秒更新 60 次
- 每 t 毫秒执行一次 c++ 代码
- C++ SQLite 查询只工作一次。我的代码有什么问题?
- 对于多少种类型的 x86 处理器,Ngen 和 .net 本机一次创建本机代码
- 如何在没有外部标志的情况下只在循环中运行一次代码
- 如何在ubuntu中创建和运行一个脚本,该脚本每5分钟运行一次并关闭一个c代码
- 在没有默认构造函数的OpenMP中,每个线程执行一次代码
- 如何只执行一段代码一次
- 代码是打印相同的值时,它应该随机生成每一次,而且它不打印数组中的第一个值
- 在精确的时间运行代码,每小时运行一次
- 如何只执行一次方法代码,尽管每帧调用一次
- 将代码复制到RAM-如何一次复制多个功能