Skip site navigation (1)Skip section navigation (2)

FreeBSD Manual Pages

  
 
  

home | help
std::call_once(3)	      C++ Standard Libary	     std::call_once(3)

NAME
       std::call_once -	std::call_once

Synopsis
	  Defined in header <mutex>
	  template<	  class	      Callable,	     class...	   Args	     >
       (since C++11)
	  void call_once( std::once_flag& flag,	Callable&& f,  Args&&...  args
       );

	  Executes  the	Callable object	f exactly once,	even if	called concur-
       rently from
	  several threads.

In detail:
	    * If, by the time std::call_once is	called,	flag indicates that  f
       was already
	      called,  std::call_once  returns	right  away  (such  a  call to
       std::call_once is
	      known as passive).
	    *	  Otherwise,	 std::call_once	    calls     INVOKE(std::for-
       ward<Callable>(f),
	      std::forward<Args>(args)...). Unlike the std::thread constructor
       or std::async,
	      the  arguments  are not moved or copied because they do not need
       to be transferred
	      to another thread	of execution (such a call to std::call_once is
       known as
	      active).

	    * If that invocation throws	an exception, it is propagated to  the
       caller of
	      std::call_once,  and  flag  is  not flipped so that another call
       will be attempted
	      (such a call to std::call_once is	known as exceptional).
	    *  If  that	 invocation  returns  normally	 (such	 a   call   to
       std::call_once is known as
	      returning),   flag   is	flipped,   and	 all  other  calls  to
       std::call_once with the same
	      flag are guaranteed to be	passive.

	  All active calls on the same flag form a single total	order consist-
       ing of zero or
	  more exceptional calls, followed by one returning call. The  end  of
       each active call
	  synchronizes-with the	next active call in that order.

	  The  return  from  the  returning call synchronizes-with the returns
       from all	passive
	  calls	on the same flag: this means  that  all	 concurrent  calls  to
       std::call_once are
	  guaranteed to	observe	any side-effects made by the active call, with
       no additional
	  synchronization.

Parameters
	  flag	  - an object, for which exactly one function gets executed
	  f	  - Callable object to invoke
	  args... - arguments to pass to the function

Return value
	  (none)

Exceptions
	    *	std::system_error   if	 any   condition   prevents  calls  to
       std::call_once from
	      executing	as specified.
	    * Any exception thrown by f.

Notes
	  If concurrent	calls to std::call_once	pass different functions f, it
       is unspecified
	  which	f will be called. The  selected	 function  runs	 in  the  same
       thread as the
	  std::call_once invocation it was passed to.

	  Initialization of function-local statics is guaranteed to occur only
       once even when
	  called  from	multiple  threads,  and	may be more efficient than the
       equivalent code
	  using	std::call_once.

	  The POSIX equivalent of this function	is pthread_once.

Example
       // Run this code

	#include <iostream>
	#include <mutex>
	#include <thread>

	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"; // this may ap-
       pear more than once
		throw std::exception();
	    }
	    std::cout << "Did not throw, call_once will	not attempt  again\n";
       // guaranteed once
	}

	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();
	}

Possible output:
	Simple example:	called once
	Throw: call_once will retry
	Throw: call_once will retry
	Throw: call_once will retry
	Did not	throw, call_once will not attempt again

	  Defect reports

	  The following	behavior-changing defect reports were applied retroac-
       tively to
	  previously published C++ standards.

	     DR	       Applied	  to		   Behavior    as    published
       Correct behavior
			      std::invalid_argument would be thrown if f
	  LWG 2080 C++11      is invalid,				   re-
       moved this error
			      but the scenario where f is invalidated is  con-
       dition
			      not specified
	  LWG  2442  C++11	the arguments were copied and/or moved	    no
       copying/moving is
			      before invocation				  per-
       formed

See also
	  once_flag helper object to ensure that call_once invokes  the	 func-
       tion only once
	  (C++11)   (class)
	  C documentation for
	  call_once

http://cppreference.com		  2024.06.10		     std::call_once(3)

Want to link to this manual page? Use this URL:
<https://man.freebsd.org/cgi/man.cgi?query=std::call_once&sektion=3&manpath=FreeBSD+Ports+15.1.quarterly>

home | help