test_once.cpp

来自「Boost provides free peer-reviewed portab」· C++ 代码 · 共 192 行

CPP
192
字号
// (C) Copyright 2006-7 Anthony Williams// Distributed under the Boost Software License, Version 1.0. (See// accompanying file LICENSE_1_0.txt or copy at// http://www.boost.org/LICENSE_1_0.txt)#include <boost/test/unit_test.hpp>#include <boost/thread/thread.hpp>#include <boost/thread/mutex.hpp>#include <boost/thread/once.hpp>boost::once_flag flag=BOOST_ONCE_INIT;int var_to_init=0;boost::mutex m;void initialize_variable(){    // ensure that if multiple threads get in here, they are serialized, so we can see the effect    boost::mutex::scoped_lock lock(m);    ++var_to_init;}void call_once_thread(){    unsigned const loop_count=100;    int my_once_value=0;    for(unsigned i=0;i<loop_count;++i)    {        boost::call_once(flag, initialize_variable);        my_once_value=var_to_init;        if(my_once_value!=1)        {            break;        }    }    boost::mutex::scoped_lock lock(m);    BOOST_CHECK_EQUAL(my_once_value, 1);}void test_call_once(){    unsigned const num_threads=20;    boost::thread_group group;    try    {        for(unsigned i=0;i<num_threads;++i)        {            group.create_thread(&call_once_thread);        }        group.join_all();    }    catch(...)    {        group.interrupt_all();        group.join_all();        throw;    }    BOOST_CHECK_EQUAL(var_to_init,1);}int var_to_init_with_functor=0;struct increment_value{    int* value;    explicit increment_value(int* value_):        value(value_)    {}        void operator()() const    {        boost::mutex::scoped_lock lock(m);        ++(*value);    }};void call_once_with_functor(){    unsigned const loop_count=100;    int my_once_value=0;    static boost::once_flag functor_flag=BOOST_ONCE_INIT;    for(unsigned i=0;i<loop_count;++i)    {        boost::call_once(functor_flag, increment_value(&var_to_init_with_functor));        my_once_value=var_to_init_with_functor;        if(my_once_value!=1)        {            break;        }    }    boost::mutex::scoped_lock lock(m);    BOOST_CHECK_EQUAL(my_once_value, 1);}void test_call_once_arbitrary_functor(){    unsigned const num_threads=20;    boost::thread_group group;    try    {        for(unsigned i=0;i<num_threads;++i)        {            group.create_thread(&call_once_with_functor);        }        group.join_all();    }    catch(...)    {        group.interrupt_all();        group.join_all();        throw;    }    BOOST_CHECK_EQUAL(var_to_init_with_functor,1);}struct throw_before_third_pass{    struct my_exception    {};    static unsigned pass_counter;        void operator()() const    {        boost::mutex::scoped_lock lock(m);        ++pass_counter;        if(pass_counter<3)        {            throw my_exception();        }    }};unsigned throw_before_third_pass::pass_counter=0;unsigned exception_counter=0;void call_once_with_exception(){    static boost::once_flag functor_flag=BOOST_ONCE_INIT;    try    {        boost::call_once(functor_flag, throw_before_third_pass());    }    catch(throw_before_third_pass::my_exception)    {        boost::mutex::scoped_lock lock(m);        ++exception_counter;    }}void test_call_once_retried_on_exception(){    unsigned const num_threads=20;    boost::thread_group group;    try    {        for(unsigned i=0;i<num_threads;++i)        {            group.create_thread(&call_once_with_exception);        }        group.join_all();    }    catch(...)    {        group.interrupt_all();        group.join_all();        throw;    }    BOOST_CHECK_EQUAL(throw_before_third_pass::pass_counter,3u);    BOOST_CHECK_EQUAL(exception_counter,2u);}boost::unit_test_framework::test_suite* init_unit_test_suite(int, char*[]){    boost::unit_test_framework::test_suite* test =        BOOST_TEST_SUITE("Boost.Threads: call_once test suite");    test->add(BOOST_TEST_CASE(test_call_once));    test->add(BOOST_TEST_CASE(test_call_once_arbitrary_functor));    test->add(BOOST_TEST_CASE(test_call_once_retried_on_exception));    return test;}

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?