std::call_once

定义于头文件 <mutex>
template< class Callable, class... Args >
void call_once( std::once_flag& flag, Callable&& f, Args&&... args );
(C++11 起)

准确执行一次可调用 (Callable) 对象 f ,即使从多个线程调用。

每组接收同一 std::once_flag 对象的 call_once 调用将符合下列要求:

目录

参数

flag - 对象,对于它只有一个函数得到执行
f - 要调用的可调用 (Callable) 对象
args... - 传递给函数的参数

返回值

(无)

异常

注意

可调用 (Callable) 对象的参数被移动或以值复制。若需要传递引用参数给可调用 (Callable) 对象,则必须包装它(例如以 std::refstd::cref )。

(C++17 前)

传递给可调用 (Callable) 对象的参数被完美转发(如同以 std::forward<Callable>(f)std::forward<Args>(args))... ),这异于 thread 构造函数或 std::async可调用 (Callable) 的用法,因为 call_once 不必转移其参数给另一执行线程,从而不必移动或复制。

(C++17 起)

函数局域静态对象的初始化保证仅发生一次,即使在从多个线程调用时,而这可能比使用 std::call_once 的等价代码更为高效。

示例

#include <iostream>
#include <thread>
#include <mutex>
 
std::once_flag flag1, flag2;
 
void simple_do_once()
{
    std::call_once(flag1, [](){ std::cout << "Simple example: called once\n"; });
}
 
void may_throw_function(bool do_throw)
{
  if (do_throw) {
    std::cout << "throw: call_once will retry\n"; // 这会出现多于一次
    throw std::exception();
  }
  std::cout << "Didn't throw, call_once will not attempt again\n"; // 保证一次
}
 
void do_once(bool do_throw)
{
  try {
    std::call_once(flag2, may_throw_function, do_throw);
  }
  catch (...) {
  }
}
 
int main()
{
    std::thread st1(simple_do_once);
    std::thread st2(simple_do_once);
    std::thread st3(simple_do_once);
    std::thread st4(simple_do_once);
    st1.join();
    st2.join();
    st3.join();
    st4.join();
 
    std::thread t1(do_once, true);
    std::thread t2(do_once, true);
    std::thread t3(do_once, false);
    std::thread t4(do_once, true);
    t1.join();
    t2.join();
    t3.join();
    t4.join();
}

可能的输出:

Simple example: called once
throw: call_once will retry
throw: call_once will retry
Didn't throw, call_once will not attempt again

参阅

(C++11)
确保 call_once 只调用函数一次的帮助对象
(类)
call_onceC 文档

版本历史

  • (当前 | 先前 2017年8月24日 (四) 07:16Fruderica讨论 | 贡献. . (3,480字节) (+361). . (撤销)
  • 当前 | 先前 2013年7月2日 (二) 11:30P12bot讨论 | 贡献 . . (3,119字节) (-71). . (Use {{lc}}. Update links. Various fixes.) (撤销)
  • 当前 | 先前 2012年11月2日 (五) 20:31P12bot讨论 | 贡献 . . (3,190字节) (+225). . (r2.7.3) (机器人添加:de, en, es, fr, it, ja, pt, ru) (撤销)
  • 当前 | 先前 2012年10月26日 (五) 03:08P12讨论 | 贡献 . . (2,965字节) (0). . (1个修订: Translate from the English version) (撤销)
  • 当前 | 先前) 2012年10月25日 (四) 12:00TranslationBot讨论 | 贡献. . (2,965字节) (+2,965). . (Translated from the English version using Google Translate)