16.3.3  call_once

16.3.3 call_ once

call_once()是命名空间std中的公有成员函数。其函数声明形式为:

978-7-111-51399-5-Chapter16-51.jpg

使用call_once()函数必然需要使用结构化标识once_flag。该结构是不透明的数据结构,在调用call_once函数时,该结构可以确保不引起数据竞争或者死锁。

978-7-111-51399-5-Chapter16-52.jpg

该结构的构造函数为:

978-7-111-51399-5-Chapter16-53.jpg

下面讲述call_once()函数的详细使用方法。

call_once()函数的执行是需要被调用的,不是被动执行,是主动执行。主动执行该函数时,应该调用INVOKE(DECAY_COPY(std::forward<Callable>(func))),DECAY_COP-Y(std::forward<Args>(args))…)。若该调用抛出异常(system_error),则该执行过程是异常的;否则,函数会返回。

once_flag相当于一个锁,使用它的线程都会在上面等待,但只有一个线程允许执行。如果该线程抛出异常,那么从等待中的线程中选择一个,重复上面的流程。

例16-10

978-7-111-51399-5-Chapter16-54.jpg

978-7-111-51399-5-Chapter16-55.jpg

例16-10的执行效果如图16-10所示。

978-7-111-51399-5-Chapter16-56.jpg

图16-10 例16-10的执行效果

由程序的执行结果可知,set_winner()函数仅被执行了1次,而线程总数目是10个。可见call_once()函数是发挥了作用的。