Thread-Per-Message


非同期メッセージの投げっぱなしバージョン。
戻り値が欲しい場合は Future パターンを使用する。


以下は増補改訂版 Java言語で学ぶデザインパターン入門 マルチスレッド編のサンプルを Boost.Thread を使って書いたコード。


main.cpp

#include <boost/shared_ptr.hpp>
#include <iostream>
#include <string>
#include "host.h"
#include "../thread_helper.h"

namespace mtdp{ namespace thread_per_message
{
    void main()
    {
        thread_helper::shared_cout("main BEGIN\n");
        boost::shared_ptr<host> h(new host());
        h->request(10, 'A');
        h->request(20, 'B');
        h->request(30, 'C');
        thread_helper::shared_cout("main END\n");
    }
}}

host.h

#ifndef MTDP_THREAD_PER_MESSAGE_HOST_H_INCLUDED
#define MTDP_THREAD_PER_MESSAGE_HOST_H_INCLUDED

#include <boost/thread.hpp>
#include <boost/shared_ptr.hpp>
#include <boost/bind.hpp>
#include <iostream>
#include "helper.h"
#include "../thread_helper.h"

namespace mtdp{ namespace thread_per_message
{
    class host
    {
    private:
        const boost::shared_ptr<helper> helper_;

        boost::thread_group group_;

    public:
        host() : helper_(new helper())
        {
        }

        ~host()
        {
            group_.join_all();
        }

        void request(int count, char c)
        {
            thread_helper::shared_cout("    request(" + to_string(count) + ", " + to_string(c) + ") BEGIN\n");
            group_.create_thread(boost::bind(&helper::handle, helper_, count, c));
            thread_helper::shared_cout("    request(" + to_string(count) + ", " + to_string(c) + ") END\n");
        }
    };
}}

#endif // MTDP_THREAD_PER_MESSAGE_HOST_H_INCLUDED

helper.h

#ifndef MTDP_THREAD_PER_MESSAGE_HELPER_H_INCLUDED
#define MTDP_THREAD_PER_MESSAGE_HELPER_H_INCLUDED

#include "../thread_helper.h"

namespace mtdp{ namespace thread_per_message
{
    class helper
    {
    public:
        void handle(int count, char c)
        {
            thread_helper::shared_cout("        handle(" + to_string(count) + ", " + to_string(c) + ") BEGIN\n");
            for (int i = 0; i < count; i++)
            {
                slowly();
                thread_helper::shared_cout(c);
            }
            thread_helper::shared_cout("\n");
            thread_helper::shared_cout("        handle(" + to_string(count) + ", " + to_string(c) + ") END\n");
        }

    private:
        void slowly()
        {
            thread_helper::sleep(100);
        }
    };
}}

#endif // MTDP_THREAD_PER_MESSAGE_HELPER_H_INCLUDED

出力結果

main BEGIN
    request(10, A) BEGIN
        handle(10, A) BEGIN
    request(10, A) END
    request(20, B) BEGIN
        handle(20, B) BEGIN
A    request(20, B) END
    request(30, C) BEGIN
AB        handle(30, C) BEGIN
    request(30, C) END
main END
ABCABCABCABCABCABCABCA
        handle(10, A) END
BCBCBCBCBCBCBCBCBCBCBCB
        handle(C20, B) END
CCCCCCCCCCCC
        handle(30, C) END

なんか出力結果が変に見えるけど、間違ってはいないはず。