スポンサーサイト

-------- | --:--

上記の広告は1ヶ月以上更新のないブログに表示されています。
新しい記事を書く事で広告が消せます。

[boost.asio] 並列処理の排他制御

2013-04-17 | 17:07

排他制御を考慮していない並列処理

次のプログラムは、Workerクラスのdo_something()内で"*"を10個印字した後、改行している。ただし、別なスレッドが"+"を印字するinterrupt()を呼び出しているため、"*"と"+"が混じってしまう。

#include <iostream>

#include <boost/thread.hpp>

class Worker{
    public:
        void do_something(){
            while(true){
                for(int i = 0 ; i < 10 ; i++){
                    boost::this_thread::sleep(boost::posix_time::milliseconds(100));
                    std::cout << "*" ;
                }
                std::cout << std::endl;
            }
        }

        void interrupt(){
            std::cout << "+";
        }
    private:
};

int main(){
    Worker w;
    boost::thread_group g;
    g.create_thread([&w](){
            while(true){
            boost::this_thread::sleep(boost::posix_time::milliseconds(40));
            w.interrupt();
            }
    });

    w.do_something();

    g.join_all();
    std::cout << "bye" << std::endl;
    return 0;
}

改良

io_serviceをメンバに追加し、interrupt()では印字処理をio_serviceにpost()し、do_something()のループ内でio_service::run()を呼び出す。これにより、"+"を印字する処理は"*"の印字が終了した後で呼び出されるようになるので、出力が混じることがなくなる。

#include <iostream>

#include <boost/asio.hpp>
#include <boost/thread.hpp>

class Worker{
    public:
        void do_something(){
            while(true){
                for(int i = 0 ; i < 10 ; i++){
                    boost::this_thread::sleep(boost::posix_time::milliseconds(100));
                    std::cout << "*" ;
                }
                std::cout << std::endl;

                io_service_.reset();
                io_service_.run();
            }
        }

        void interrupt(){
            io_service_.post([](){
            std::cout << "+";
            });
        }
    private:
        boost::asio::io_service io_service_;
};

int main(){
    Worker w;
    boost::thread_group g;
    g.create_thread([&w](){
            while(true){
            boost::this_thread::sleep(boost::posix_time::milliseconds(40));
            w.interrupt();
            }
    });

    w.do_something();

    g.join_all();
    std::cout << "bye" << std::endl;
    return 0;
}
スポンサーサイト
上記広告は1ヶ月以上更新のないブログに表示されています。新しい記事を書くことで広告を消せます。