[모던C++입문] 4.6 동시성

    4.6 동시성

    • c++11에서 동시성 기능이 처음으로 도입되었다.
      • thread: 새로운 실행 경로를 위한 클래스
      • async: 함수를 비동기로 호출
      • atomic: 인터리브(Interleave) 되지 않은 값에 접근하기 위한 클래스 템플릿
      • mutex: 상ㅎ호 배타적인 실행을 조정하는 클래스
      • future: thread로부터 결과를 받기위한 클래스 템플릿
      • promise: future를 위해 값을 저장하는 템플릿

    • 여기서는 비동기로 동작하면 인터럽트 가능한 프로그램을 구현해보고자 한다
      • 비동기식(Asynchrony): 프로그램을 실행하는 동안 다음모델에서 작업 가능
      • 인터럽트 가능성(Interruptibility): 새로운 모델이 더 좋으면 이전 모델을 중단
    class interruptible_iteration
    {
    public:
        interruptible_iteration(basic_iteration<double>& iter)
            : iter(iter), interrupted(false) {}
    
        bool finished(double r)
        {
            return iter.finished(r) || interrupted.load();
        }
    
        void interrupt() { interrupted = true; }
        bool is_interrupted() const { return interrupted.load(); }
    private:
        basic_iteration<double>& iter;
        std::atomic<bool> interrupted;
    }
    
    template<typename Solver>
    class async_executor
    {
    public:
        async_executor(const Solver& solver)
            : my_solver(solver), my_iter{}, my_thread{} {}
    
        template<typename VectorB, typename VectorX, typename Iteration>
        void start_solve(const VectorB& b, VectorX& x, Iteration& iter) const
        {
            my_iter.set_iter(iter);
            my_thread = std::thread(
                [this, &b, &x]()
                {
                    return my_solver.solve(b, x, my_iter);
                }
            );
        }
    
        int wait()
        {
            my_thread.join();
            return my_iter.error_code();
        }
    
        int interrupt()
        {
            my_iter.interrupt();
            return wait();
        }
    
        bool finished() const { return my_iter.iter->finished(); }
    private:
        Solver my_solver;
        mutable interruptible_iteration my_iter;
        mutable std::thread my_thread;
    }
    • 다음은 위 클래스를 이용한 비동기 실행에 대한 의사코드이다
    while(!happy(science_foundation))
    {
        discretize_model();
        auto my_solver = itl::make_cg_solver(A, PC);
        itl::async_executor<decltype(my_solver)> async_exec(my_solver);
        async_exec.start_solve(x, b, iter);
        play_with_model();
    
        if( found_better_model)
            async_exec.interrupt();
        else
            async_exec.wait();
    }
    반응형

    댓글

    Designed by JB FACTORY