这是用户在 2024-11-7 16:59 为 https://legacy.cplusplus.com/reference/mutex/call_once/?kw=call_once 保存的双语快照页面,由 沉浸式翻译 提供双语支持。了解如何保存?
[try Beta version]
Not logged in
You were redirected to cplusplus.com/call_once || See search results for: "call_once"
public member function
<mutex>

std::call_once

template <class Fn, class... Args>
  void call_once (once_flag& flag, Fn&& fn, Args&&... args);
Call function once
Calls fn passing args as arguments, unless another thread has already executed (or is currently executing) a call to call_once with the same flag.

If another thread is already actively executing a call to call_once with the same flag, it causes a passive execution: Passive executions do not call fn but do not return until the active execution itself has returned, and all visible side effects are synchronized at that point among all concurrent calls to this function with the same flag.

If an active call to call_once ends by throwing an exception (which is propagated to its calling thread) and passive executions exist, one is selected among these passive executions, and called to be the new active call instead.

Note that once an active execution has returned, all current passive executions and future calls to call_once (with the same flag) also return without becoming active executions.

The active execution uses decay copies of the lvalue or rvalue references of fn and args, ignoring the value returned by fn.

Parameters

flag
Object used by the function to track the state of invocations.
Using the same object for calls in different threads, results in a single call if called concurrently.
If flag has a state that is not valid, the function throws a system_error exception with an invalid_argument error condition.
If flag has a state that is not valid, the call causes undefined behavior.
call_once is a specific type defined in header <mutex> to be used as argument to this function.
fn
A pointer to function, pointer to member, or any kind of move-constructible function object (i.e., an object whose class defines operator(), including closures and function objects).
The return value (if any) is ignored.
args...
Arguments passed to the call to fn. Their types shall be move-constructible.
If fn is a member pointer, the first argument shall be an object for which that member is defined (or a reference, or a pointer to it).

Return Value

none

Example

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
// call_once example
#include <iostream>       // std::cout
#include <thread>         // std::thread, std::this_thread::sleep_for
#include <chrono>         // std::chrono::milliseconds
#include <mutex>          // std::call_once, std::once_flag

int winner;
void set_winner (int x) { winner = x; }
std::once_flag winner_flag;

void wait_1000ms (int id) {
  // count to 1000, waiting 1ms between increments:
  for (int i=0; i<1000; ++i)
    std::this_thread::sleep_for(std::chrono::milliseconds(1));
  // claim to be the winner (only the first such call is executed):
  std::call_once (winner_flag,set_winner,id);
}

int main ()
{
  std::thread threads[10];
  // spawn 10 threads:
  for (int i=0; i<10; ++i)
    threads[i] = std::thread(wait_1000ms,i+1);

  std::cout << "waiting for the first among 10 threads to count 1000 ms...\n";

  for (auto& th : threads) th.join();
  std::cout << "winner thread: " << winner << '\n';

  return 0;
}


Possible output (winner may vary):

waiting for the first among 10 threads to count 1000 ms...
winner thread: 2

Data races

The function modifies flag, and accesses fn and args to create decay copies of their lvalue or rvalue references.

Exception safety

If the function itself fails, it throws a system_error exception, leaving all objects in a valid state (basic guarantee).
Otherwise, active executions provide the same level of guarantees as the operation performed on the arguments.

See also

Reference