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 call_once	is called, flag	indicates that	f  was
       already called,
	      call_once	 returns right away (such a call to call_once is known
       as passive).

	    * Otherwise, call_once invokes std::forward<Callable>(f) with  the
       arguments
	      std::forward<Args>(args)...  (as	if by std::invoke). Unlike the
       std::thread
	      constructor or std::async, the arguments are not moved or	copied
       because they
	      don't need to be transferred to  another	thread	of  execution.
       (such a call to
	      call_once	is known as active).

		     *	If  that  invocation throws an exception, it is	propa-
       gated to	the caller
		       of call_once, and the flag is not flipped so  that  an-
       other call will be
		       attempted  (such	a call to call_once is known as	excep-
       tional).
		     * If that invocation returns normally  (such  a  call  to
       call_once is known
		       as returning), the flag is flipped, and all other calls
       to 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
       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  call_once
       from executing as
	      specified
	    * any exception thrown by f

Notes
	  If  concurrent  calls	to call_once pass different functions f, it is
       unspecified which
	  f will be called. The	selected function runs in the same  thread  as
       the 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 <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"; // this may	appear
       more than once
	    throw std::exception();
	  }
	  std::cout << "Didn't 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
	Didn't 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
	  LWG 2442 C++11      the arguments are	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)

http://cppreference.com		  2022.07.31		     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.0>

home | help