LoginSignup
1
2

More than 5 years have passed since last update.

コンピュータ将棋ソフトとの対局サーバーを立てよう<その12>

Last updated at Posted at 2017-03-14

前回の記事 : http://qiita.com/muzudho1/items/3d292bafc4a8fa54eb43

cppをバックグラウンドで走らせて

フォアグラウンドで cpp を叩く。

# cd ../csharp_service
# ./tamesi35a2_cs.exe

Unhandled Exception:
System.Exception: コマンドライン引数に「--msgqueue キュー名 寿命 キュー名 寿命」を指定しろだぜ☆(^~^)
エンキュー先、デキュー先の順番な☆(^▽^)
寿命は durable, autodelete, passive, exclusive のいずれかで、
複合指定にはまだ対応していないぜ☆(>_<)
  at Program.Main (System.String[] args) <0x40857270 + 0x0041f> in <filename unknown>:0
[ERROR] FATAL UNHANDLED EXCEPTION: System.Exception: コマンドライン引数に「--msgqueue キュー名 寿命 キュー名 寿命」を指定しろだぜ☆(^~^)
エンキュー先、デキュー先の順番な☆(^▽^)
寿命は durable, autodelete, passive, exclusive のいずれかで、
複合指定にはまだ対応していないぜ☆(>_<)
  at Program.Main (System.String[] args) <0x40857270 + 0x0041f> in <filename unknown>:0

起動してすぐに落ちた。

tamesi35a2_cs.exe ではなく、tamesi34_cs.exe を起動したいのだった。

# jobs
[1]+  Running                 ./tamesi35a2_cpp.exe --msgqueue 1117 durable 1116 durable 2> ./tamesi35a2_cpp.err.log &  (wd: /home/★user/shogi/cpp_service)

Job はまだ生きている。

root@tk2-217-18401:/home/★user/shogi/csharp_service# ./tamesi34_cs.exe
削除したいキューがあれば名前を、無ければ空文字列を入れろだぜ☆(^~^)
キュー名を入力    : キューを削除します
空文字列で[Enter] : 次のステップへ進む
Name or empty ? >
エンキュー先のメッセージ・キューの名前を入れろだぜ☆(^~^)
Queue name? > 1116
エンキュー先のメッセージ・キューの寿命を、足し算して答えろだぜ☆(^~^)
(1) durable    : RabbitMQが止まってもキューを残す
(2) autodelete : コンシューマーが1人も接続していなかったら消す
(4) passive    : キューが存在するかどうかチェックするだけ。中身見ない時これ
(8) exclusive  : この接続でだけ使える。この接続が切れたら消す
Number ? > 3
デキュー先のメッセージ・キューの名前を入れろだぜ☆(^~^)
Queue name? > 1117
デキュー先のメッセージ・キューの寿命を、足し算して答えろだぜ☆(^~^)
(1) durable    : RabbitMQが止まってもキューを残す
(2) autodelete : コンシューマーが1人も接続していなかったら消す
(4) passive    : キューが存在するかどうかチェックするだけ。中身見ない時これ
(8) exclusive  : この接続でだけ使える。この接続が切れたら消す
Number ? > 3
tamesi34_cs.cs Dump
    name_queues         [ENQUEUE_INDEX]    =[1116]
    lifeSpan_queues     [ENQUEUE_INDEX]    =[Durable, Autodelete]
    durable_lifeSpans   [ENQUEUE_INDEX]    =[True]
    autodelete_lifeSpans[ENQUEUE_INDEX]    =[True]
    passive_lifeSpans   [ENQUEUE_INDEX]    =[False]
    exclusive_lifeSpans [ENQUEUE_INDEX]    =[False]
    ----
    name_queues         [DEQUEUE_INDEX]    =[1117]
    lifeSpan_queues     [DEQUEUE_INDEX]    =[Durable, Autodelete]
    durable_lifeSpans   [DEQUEUE_INDEX]    =[True]
    autodelete_lifeSpans[DEQUEUE_INDEX]    =[True]
    passive_lifeSpans   [DEQUEUE_INDEX]    =[False]
    exclusive_lifeSpans [DEQUEUE_INDEX]    =[False]
    ----
    name_queues         [DELETEQUEUE_INDEX]=[]
    lifeSpan_queues     [DELETEQUEUE_INDEX]=[0]
    durable_lifeSpans   [DELETEQUEUE_INDEX]=[False]
    autodelete_lifeSpans[DELETEQUEUE_INDEX]=[False]
    passive_lifeSpans   [DELETEQUEUE_INDEX]=[False]
    exclusive_lifeSpans [DELETEQUEUE_INDEX]=[False]
    ----

(tamesi34_cs.cs?) GetChannel index = [1]
    name_queues[index] = [1117]
    passive_lifeSpans[index] = [False]
    durable_lifeSpans[index] = [True]
    exclusive_lifeSpans[index] = [False]
    autodelete_lifeSpans[index] = [True]
    nowait は仮に false 固定
    arguments は仮に null 固定
終了するときは[Ctrl]+[C]キーを押せだぜ☆(^~^)
エンキューするときはメッセージを打ち込んで[Enter]キーを押せだぜ☆(^◇^)
Enqueue? >
  • Windows10 / RabbitMQ では durable
  • Ubuntu16.04 / RabbitMQ では durable + autodelete

が初期設定になっている現環境実装なことは前回の記事で調べた。

Enqueue? > usi
tamesi34_cs.cs Dump
    name_queues         [ENQUEUE_INDEX]    =[1116]
    lifeSpan_queues     [ENQUEUE_INDEX]    =[Durable, Autodelete]
    durable_lifeSpans   [ENQUEUE_INDEX]    =[True]
    autodelete_lifeSpans[ENQUEUE_INDEX]    =[True]
    passive_lifeSpans   [ENQUEUE_INDEX]    =[False]
    exclusive_lifeSpans [ENQUEUE_INDEX]    =[False]
    ----
    name_queues         [DEQUEUE_INDEX]    =[1117]
    lifeSpan_queues     [DEQUEUE_INDEX]    =[Durable, Autodelete]
    durable_lifeSpans   [DEQUEUE_INDEX]    =[True]
    autodelete_lifeSpans[DEQUEUE_INDEX]    =[True]
    passive_lifeSpans   [DEQUEUE_INDEX]    =[False]
    exclusive_lifeSpans [DEQUEUE_INDEX]    =[False]
    ----
    name_queues         [DELETEQUEUE_INDEX]=[]
    lifeSpan_queues     [DELETEQUEUE_INDEX]=[0]
    durable_lifeSpans   [DELETEQUEUE_INDEX]=[False]
    autodelete_lifeSpans[DELETEQUEUE_INDEX]=[False]
    passive_lifeSpans   [DELETEQUEUE_INDEX]=[False]
    exclusive_lifeSpans [DELETEQUEUE_INDEX]=[False]
    ----

(tamesi34_cs.cs?) GetChannel index = [0]
    name_queues[index] = [1116]
    passive_lifeSpans[index] = [False]
    durable_lifeSpans[index] = [True]
    exclusive_lifeSpans[index] = [False]
    autodelete_lifeSpans[index] = [True]
    nowait は仮に false 固定
    arguments は仮に null 固定

Unhandled Exception:
RabbitMQ.Client.Exceptions.OperationInterruptedException: The AMQP operation was interrupted: AMQP close-reason, initiated by Peer, code=406, text="PRECONDITION_FAILED - inequivalent arg 'auto_delete' for queue '1116' in vhost '/': received 'true' but current is 'false'", classId=50, methodId=10, cause=
  at RabbitMQ.Client.Impl.SimpleBlockingRpcContinuation.GetReply () <0x403b9410 + 0x00107> in <filename unknown>:0
  at RabbitMQ.Client.Impl.ModelBase.ModelRpc (RabbitMQ.Client.Impl.MethodBase method, RabbitMQ.Client.Impl.ContentHeaderBase header, System.Byte[] body) <0x403b7290 + 0x000fd> in <filename unknown>:0
  at RabbitMQ.Client.Framing.Impl.v0_8.Model.QueueDeclare (System.String queue, Boolean passive, Boolean durable, Boolean exclusive, Boolean autoDelete, Boolean nowait, IDictionary arguments) <0x403bc340 + 0x00113> in <filename unknown>:0
  at UsagiMQ.Program.GetChannel (Int32 index) <0x4037cd10 + 0x0045c> in <filename unknown>:0
  at UsagiMQ.Program.Enqueue (System.String message) <0x403bd420 + 0x00013> in <filename unknown>:0
  at UsagiMQ.Program.Main (System.String[] args) <0x40377d50 + 0x009a7> in <filename unknown>:0
[ERROR] FATAL UNHANDLED EXCEPTION: RabbitMQ.Client.Exceptions.OperationInterruptedException: The AMQP operation was interrupted: AMQP close-reason, initiated by Peer, code=406, text="PRECONDITION_FAILED - inequivalent arg 'auto_delete' for queue '1116' in vhost '/': received 'true' but current is 'false'", classId=50, methodId=10, cause=
  at RabbitMQ.Client.Impl.SimpleBlockingRpcContinuation.GetReply () <0x403b9410 + 0x00107> in <filename unknown>:0
  at RabbitMQ.Client.Impl.ModelBase.ModelRpc (RabbitMQ.Client.Impl.MethodBase method, RabbitMQ.Client.Impl.ContentHeaderBase header, System.Byte[] body) <0x403b7290 + 0x000fd> in <filename unknown>:0
  at RabbitMQ.Client.Framing.Impl.v0_8.Model.QueueDeclare (System.String queue, Boolean passive, Boolean durable, Boolean exclusive, Boolean autoDelete, Boolean nowait, IDictionary arguments) <0x403bc340 + 0x00113> in <filename unknown>:0
  at UsagiMQ.Program.GetChannel (Int32 index) <0x4037cd10 + 0x0045c> in <filename unknown>:0
  at UsagiMQ.Program.Enqueue (System.String message) <0x403bd420 + 0x00013> in <filename unknown>:0
  at UsagiMQ.Program.Main (System.String[] args) <0x40377d50 + 0x009a7> in <filename unknown>:0

すると、コンシューマーは durable+autodelete だが、プロデューサーは urable だけなのだろうか?

./tamesi34_cs.exe の設定プロンプトでプロデューサーの寿命は 3 ではなく 1 に変えよう。

# jobs
[1]+  Running                 ./tamesi35a2_cpp.exe --msgqueue 1117 durable 1116 durable 2> ./tamesi35a2_cpp.err.log &  (wd: /home/★user/shogi/cpp_service)

バックグラウンド・プロセスはまだ生きている。

root@tk2-217-18401:/home/★user/shogi/csharp_service# ./tamesi34_cs.exe
削除したいキューがあれば名前を、無ければ空文字列を入れろだぜ☆(^~^)
キュー名を入力    : キューを削除します
空文字列で[Enter] : 次のステップへ進む
Name or empty ? >
エンキュー先のメッセージ・キューの名前を入れろだぜ☆(^~^)
Queue name? > 1116
エンキュー先のメッセージ・キューの寿命を、足し算して答えろだぜ☆(^~^)
(1) durable    : RabbitMQが止まってもキューを残す
(2) autodelete : コンシューマーが1人も接続していなかったら消す
(4) passive    : キューが存在するかどうかチェックするだけ。中身見ない時これ
(8) exclusive  : この接続でだけ使える。この接続が切れたら消す
Number ? > 1
デキュー先のメッセージ・キューの名前を入れろだぜ☆(^~^)
Queue name? > 1117
デキュー先のメッセージ・キューの寿命を、足し算して答えろだぜ☆(^~^)
(1) durable    : RabbitMQが止まってもキューを残す
(2) autodelete : コンシューマーが1人も接続していなかったら消す
(4) passive    : キューが存在するかどうかチェックするだけ。中身見ない時これ
(8) exclusive  : この接続でだけ使える。この接続が切れたら消す
Number ? > 3
tamesi34_cs.cs Dump
    name_queues         [ENQUEUE_INDEX]    =[1116]
    lifeSpan_queues     [ENQUEUE_INDEX]    =[Durable]
    durable_lifeSpans   [ENQUEUE_INDEX]    =[True]
    autodelete_lifeSpans[ENQUEUE_INDEX]    =[False]
    passive_lifeSpans   [ENQUEUE_INDEX]    =[False]
    exclusive_lifeSpans [ENQUEUE_INDEX]    =[False]
    ----
    name_queues         [DEQUEUE_INDEX]    =[1117]
    lifeSpan_queues     [DEQUEUE_INDEX]    =[Durable, Autodelete]
    durable_lifeSpans   [DEQUEUE_INDEX]    =[True]
    autodelete_lifeSpans[DEQUEUE_INDEX]    =[True]
    passive_lifeSpans   [DEQUEUE_INDEX]    =[False]
    exclusive_lifeSpans [DEQUEUE_INDEX]    =[False]
    ----
    name_queues         [DELETEQUEUE_INDEX]=[]
    lifeSpan_queues     [DELETEQUEUE_INDEX]=[0]
    durable_lifeSpans   [DELETEQUEUE_INDEX]=[False]
    autodelete_lifeSpans[DELETEQUEUE_INDEX]=[False]
    passive_lifeSpans   [DELETEQUEUE_INDEX]=[False]
    exclusive_lifeSpans [DELETEQUEUE_INDEX]=[False]
    ----

(tamesi34_cs.cs?) GetChannel index = [1]
    name_queues[index] = [1117]
    passive_lifeSpans[index] = [False]
    durable_lifeSpans[index] = [True]
    exclusive_lifeSpans[index] = [False]
    autodelete_lifeSpans[index] = [True]
    nowait は仮に false 固定
    arguments は仮に null 固定
終了するときは[Ctrl]+[C]キーを押せだぜ☆(^~^)
エンキューするときはメッセージを打ち込んで[Enter]キーを押せだぜ☆(^◇^)
Enqueue? > usi
tamesi34_cs.cs Dump
    name_queues         [ENQUEUE_INDEX]    =[1116]
    lifeSpan_queues     [ENQUEUE_INDEX]    =[Durable]
    durable_lifeSpans   [ENQUEUE_INDEX]    =[True]
    autodelete_lifeSpans[ENQUEUE_INDEX]    =[False]
    passive_lifeSpans   [ENQUEUE_INDEX]    =[False]
    exclusive_lifeSpans [ENQUEUE_INDEX]    =[False]
    ----
    name_queues         [DEQUEUE_INDEX]    =[1117]
    lifeSpan_queues     [DEQUEUE_INDEX]    =[Durable, Autodelete]
    durable_lifeSpans   [DEQUEUE_INDEX]    =[True]
    autodelete_lifeSpans[DEQUEUE_INDEX]    =[True]
    passive_lifeSpans   [DEQUEUE_INDEX]    =[False]
    exclusive_lifeSpans [DEQUEUE_INDEX]    =[False]
    ----
    name_queues         [DELETEQUEUE_INDEX]=[]
    lifeSpan_queues     [DELETEQUEUE_INDEX]=[0]
    durable_lifeSpans   [DELETEQUEUE_INDEX]=[False]
    autodelete_lifeSpans[DELETEQUEUE_INDEX]=[False]
    passive_lifeSpans   [DELETEQUEUE_INDEX]=[False]
    exclusive_lifeSpans [DELETEQUEUE_INDEX]=[False]
    ----

(tamesi34_cs.cs?) GetChannel index = [0]
    name_queues[index] = [1116]
    passive_lifeSpans[index] = [False]
    durable_lifeSpans[index] = [True]
    exclusive_lifeSpans[index] = [False]
    autodelete_lifeSpans[index] = [False]
    nowait は仮に false 固定
    arguments は仮に null 固定
 Enqueue(^q^) usi
Enqueue? >

usi はエンキューできたが、応答がこない。 tamesi35a2_cpp.exe が落ちたのだろうか?

[Ctrl] + [C]

[1]+  Aborted                 ./tamesi35a2_cpp.exe --msgqueue 1117 durable 1116 durable 2> ./tamesi35a2_cpp.err.log  (wd: /home/★user/shogi/cpp_service)
(wd now: /home/★user/shogi/csharp_service)

アボート(強制終了)している。

# nano tamesi35a2_cpp.err.log
tamesi35a2_cpp.exe: ev.c:3541: ev_run: Assertion `("libev: ev_loop recursion during release detected", ((loop)->loop_done) != 0x80)' failed.

前回の記事の知見で改造する。

  • シングルトン
  • スレッド
  • プロデューサーは durable、コンシューマーは durable+autodelete

この2つで。

まずシングルトンにしよう

おっと、その前に tamesi35a2_cpp.cpp を複数寿命指定に対応させたい。

tamesi35a2_cpp.cpp

//--------------------------------------------------------------------------------
// OS      : Windows10 : // このプログラムは動かない
//
// OS      : Ubuntu 16.04
// Library : libev
//         : Install   : Command  : sudo apt-get update
//                                : sudo apt-get install libev-dev
// Service : RabbitMQ
//         : Reference : Web site : Top page http://www.rabbitmq.com/
//         : Install   : Web site : Installing on Debian / Ubuntu http://www.rabbitmq.com/install-debian.html
//         : Manual    : Command  : man rabbitmqctl
//         : Start     : Command  : rabbitmq-server
//         : Stop      : Command  : rabbitmqctl stop
//         : Check     : Command  : rabbitmqctl status
//         :           : Command  : rabbitmqctl list_queues
// Library : AMQP-CPP
//         : Reference : Web site : AMQP-CPP README.md https://github.com/CopernicaMarketingSoftware/AMQP-CPP
//         : Reference : Web site : QueueDeclare http://docs.spring.io/spring-amqp-net/docs/1.0.x/api/html/Spring.Messaging.Amqp.Rabbit~Spring.Messaging.Amqp.Rabbit.Connection.CachedModel~QueueDeclare(String,Boolean,Boolean,Boolean,Boolean,Boolean,IDictionary).html
//         : Reference : Web site : EventingBasicConsumer https://www.rabbitmq.com/releases/rabbitmq-dotnet-client/v1.4.0/rabbitmq-dotnet-client-1.4.0-net-2.0-htmldoc/type-RabbitMQ.Client.Events.EventingBasicConsumer.html
//         : Reference : Web site : BasicConsume https://www.rabbitmq.com/releases/rabbitmq-dotnet-client/v1.4.0/rabbitmq-dotnet-client-1.4.0-net-2.0-htmldoc/type-RabbitMQ.Client.IModel.html#method-M:RabbitMQ.Client.IModel.BasicConsume(System.UInt16,System.String,System.Boolean,System.Collections.IDictionary,RabbitMQ.Client.IBasicConsumer)
//         : Reference : Web site : C#でconstな配列を実現する (もっとクールにプログラミング) http://pgnote.net/?p=885
//         : Reference : Web site : AMQP-CPP (docsforge.com) http://docsforge.com/11/AMQP-CPP/docs/latest/namespace-AMQP/class-TcpConnection/
//
// Program : this
//         : Compile   : Command  : g++ -std=c++11 tamesi35a2_cpp.cpp -o tamesi35a2_cpp.exe -lev -lamqpcpp -pthread
//         : Execute   : Command  : // バックグラウンドで実行
//                                : ./tamesi35a2_cpp.exe --enqueue 1117 durable autodelete --dequeue 1116 durable autodelete 2> ./tamesi35a2_cpp.err.log &
//         : Stop      : Typing   : [Ctrl]+[C]
//--------------------------------------------------------------------------------
//
// メッセージの末尾に daze を付けます。
// デキューは「1112」、エンキューは「1113」キューに向けて行います。
// 標準入出力は、キーボード、画面には接続しないようにします。

#include <string> // std::string
#include <iostream> // std::cout
#include <sstream> // std::ostringstream
#include <chrono>
#include <thread> // sleep_for
#include <future> // thread

// プロセス間通信用
#include <ev.h>
#include <amqpcpp.h>
#include <amqpcpp/libev.h>

// このプログラム内だけで使われる数字。AMQP-CPPでの実装とは異なる。
// AMQP-CPPでの実装 : AMQP::durable=[1] AMQP::autodelete=[2] AMQP::passive=[8] AMQP::exclusive=[512]
enum LifeSpanType
{
    // RabbitMQが止まってもキューを残す
    durable = 1,
    // コンシューマーが1人も接続していなかったら消す
    autodelete = 0x1 << 1,
    // キューが存在するかどうかチェックするだけ。中身見ない時これ
    passive = 0x1 << 2,
    // この接続でだけ使える。この接続が切れたら消す
    exclusive = 0x1 << 3
};

static AMQP::Address ADDRESS{ "amqp://localhost:5672" };
// 0 : enqueue用設定
// 1 : dequeue用設定
static const int ENQUEUE_INDEX = 0;
static const int DEQUEUE_INDEX = 1;
static const int NUM_INDEX = 2;
static std::string name_queues[] = { "1117", "1116" };
static LifeSpanType lifeSpan_queues[] = { (LifeSpanType)0, (LifeSpanType)0 };
static LifeSpanType LifeSpanString_To_Enum(std::string lifeSpan)
{
    if ("durable"==lifeSpan) {
        return durable;
    } else if ("autodelete" == lifeSpan) {
        return autodelete;
    } else if ("passive" == lifeSpan) {
        return passive;
    } else if ("exclusive" == lifeSpan) {
        return exclusive;
    } else {
        std::cerr << "未対応のlifeSpan [" << lifeSpan << "]";
        exit(1);
    }
}
static int LifeSpanString_To_AmqpInt(LifeSpanType lifeSpan)
{
    if (durable == lifeSpan) {
        return AMQP::durable;
    }
    else if (autodelete == lifeSpan) {
        return AMQP::autodelete;
    }
    else if (passive == lifeSpan) {
        return AMQP::passive;
    }
    else if (exclusive == lifeSpan) {
        return AMQP::exclusive;
    }
    else {
        std::cerr << "未対応のlifeSpan [" << lifeSpan << "]";
        exit(1);
    }
}

static std::string Dump()
{
    static std::ostringstream sb;
    sb << "tamesi35a2_cs.cs Dump" << std::endl
        << "    name_queues         [ENQUEUE_INDEX]    =[" << name_queues[ENQUEUE_INDEX] << "]"
        << "    lifeSpan_queues     [ENQUEUE_INDEX]    =[" << lifeSpan_queues[ENQUEUE_INDEX] << "]"
        << "    ----"
        << "    name_queues         [DEQUEUE_INDEX]    =[" << name_queues[DEQUEUE_INDEX] << "]"
        << "    lifeSpan_queues     [DEQUEUE_INDEX]    =[" << lifeSpan_queues[DEQUEUE_INDEX] << "]"
        << "    ----";
    return sb.str();
}

// 接続はシングルトンにします
//auto* loop = EV_DEFAULT;
//struct ev_loop** loop_queues = { EV_DEFAULT, EV_DEFAULT };


/// <summary>
/// 回転式バッファー。
/// これはメイン・スレッドに置く。
/// デキューのスレッドでエンキューすることはできない。
/// デキュー処理は、回転式バッファーを仲介にしてエンキュー処理にメッセージを渡す。
/// </summary>
namespace rotationBuffer
{
    const int bufferSize = 100;
    static std::string buffer[bufferSize] = {};
    static int bufferCursors[2] = { 0, 0 };
    const int PUT_INDEX = 0;
    const int GET_INDEX = 1;

    std::mutex _mutex;
    static void putMessage(std::string message)
    {
        std::unique_lock<std::mutex> lock(_mutex);
        buffer[bufferCursors[PUT_INDEX]] = message;
        bufferCursors[PUT_INDEX]++;
        if (!(bufferCursors[PUT_INDEX] < bufferSize))
        {
            bufferCursors[PUT_INDEX] = 0;
        }
    }
    static std::string getMessage()
    {
        std::unique_lock<std::mutex> lock(_mutex);
        if ("" != buffer[bufferCursors[GET_INDEX]])
        {
            std::string message = buffer[bufferCursors[GET_INDEX]];
            buffer[bufferCursors[GET_INDEX]] = "";
            bufferCursors[GET_INDEX]++;
            if (!(bufferCursors[GET_INDEX] < bufferSize))
            {
                bufferCursors[GET_INDEX] = 0;
            }
            return message;
        }
        return "";
    }
}

// メッセージキューにエンキュー
static void enqueue(std::string message)
{
    // エンキュー用の接続
    struct ev_loop* loop;
    AMQP::LibEvHandler handler{ loop };
    //AMQP::LibEvHandler handler{ loop_queues[ENQUEUE_INDEX] };
    AMQP::TcpConnection connection{ &handler, ADDRESS };
    AMQP::TcpChannel channel{ &connection };

    std::string exchange_name = "myexchange";
    std::string routing_key = "";

    int lifeSpan = LifeSpanString_To_AmqpInt(lifeSpan_queues[ENQUEUE_INDEX]);

    channel.declareQueue(name_queues[ENQUEUE_INDEX], lifeSpan)
        .onError([&lifeSpan](const char* errMsg) {
        std::cerr << "error declaring queue: " << errMsg << " lifeSpan=[" << lifeSpan << "]" << "\n";
    });

    channel.bindQueue(exchange_name, name_queues[ENQUEUE_INDEX], routing_key)
        .onSuccess([&connection, &channel, &exchange_name, &routing_key, &message]() {

        if (!channel.publish(exchange_name, routing_key, message.c_str(), message.size())) {
            std::cerr << "failed to publish?\n";
        }

        // break in ev loop.
        connection.close();
    });

    // このループは、パブリッシュ後に抜ける
    ev_run(loop);
    //ev_run(loop_queues[ENQUEUE_INDEX]);
}

// 受信できたときに割り込んでくる処理
// startConsume() しておくこと。
static std::string dequeue() {
    std::string message;

    while ("" == message)
    {
        message = rotationBuffer::getMessage();
    }

    return message;
}

//// メッセージ・キューの送信を担当
//static void workProduce()
//{
//
//}

// メッセージ・キューの監視を開始
static void workConsume()
{
    // Connect to the AMQP service.
    struct ev_loop* loop;
    AMQP::LibEvHandler handler{ loop };
    //AMQP::LibEvHandler handler(loop_queues[DEQUEUE_INDEX]);
    AMQP::TcpConnection connection(&handler, ADDRESS);
    AMQP::TcpChannel channel(&connection);

    // I will go to the front of the box named "1111".
    int lifeSpan = LifeSpanString_To_AmqpInt(lifeSpan_queues[DEQUEUE_INDEX]);
    channel.declareQueue(name_queues[DEQUEUE_INDEX], lifeSpan);

    // I look inside the box.
    auto errorCb = [&lifeSpan](const char *errMsg) {
        std::cerr << "My ID watching failed [" << errMsg << "] lifeSpan=[" << lifeSpan << "]" << std::endl;
    };
    auto messageCb = [&channel](const AMQP::Message &message, uint64_t deliveryTag, bool redelivered) {

        std::string myString(message.body(), message.bodySize());
        rotationBuffer::putMessage(myString);

        channel.ack(deliveryTag);
    };
    channel.consume(name_queues[DEQUEUE_INDEX])
        .onReceived(messageCb)
        .onError(errorCb);

    // I will keep on forever.
    ev_run(loop);
    //ev_run(loop_queues[DEQUEUE_INDEX], 0);

    // I will not come here.
    return;
}

int main(int argc, char* argv[])
{
    std::cout << "Welcome! AMQP::durable=[" << AMQP::durable << "] AMQP::autodelete=[" << AMQP::autodelete << "] AMQP::passive=[" << AMQP::passive << "] AMQP::exclusive=[" << AMQP::exclusive << "]" << std::endl;

    // 引数の解析
    {
        // プログラム名を省き、コマンドライン引数だけをつなげる。
        std::string cmdArg;
        for (int i = 1; i < argc; ++i)
        {
            cmdArg += std::string(argv[i]) + " ";
        }
        std::istringstream data(cmdArg);

        // 与件
        // 「--enqueue 1117 durable autodelete --dequeue 1116 durable autodelete」
        // 寿命は可変個数設定可能「durable」「autodelete」「passive」「exclusive」

        // 受け皿
        std::string titles[2]; // 結果はこれらの配列に入れる
        std::vector<std::vector<std::string>> lifespans;

        // 記憶
        int m0 = -1; // 0:enqueue, 1:dequeue

        // 解析器
        std::string a;
        while (!data.eof()) {
            data >> a;
            if ("--enqueue" == a.substr(0, 2))
            {
                m0 = 0;
                titles[m0] = a.substr(2); // 最初の2文字「--」の次から
                lifespans.push_back(std::vector<std::string>()); // リストの中にリストを準備
            }
            else if ("--dequeue" == a.substr(0, 2))
            {
                m0 = 1;
                titles[m0] = a.substr(2); // 最初の2文字「--」の次から
                lifespans.push_back(std::vector<std::string>()); // リストの中にリストを準備
            }
            else { lifespans[m0].push_back(a); } // 要素数-1 で最後の要素

            std::cout << "a=[" << a << "]" << std::endl;
        }

        // エンキュー
        m0 = 0;
        name_queues[ENQUEUE_INDEX] = titles[m0];
        lifeSpan_queues[ENQUEUE_INDEX] = (LifeSpanType)0;
        {
            for (std::string lifespan : lifespans[m0])
            {
                lifeSpan_queues[ENQUEUE_INDEX] = (LifeSpanType)((int)lifeSpan_queues[ENQUEUE_INDEX] | (int)LifeSpanString_To_Enum(lifespan));
            }
        }
        m0 = 1;
        name_queues[DEQUEUE_INDEX] = titles[m0];
        {
            for (std::string lifespan : lifespans[m0])
            {
                lifeSpan_queues[DEQUEUE_INDEX] = (LifeSpanType)((int)lifeSpan_queues[DEQUEUE_INDEX] | (int)LifeSpanString_To_Enum(lifespan));
            }
        }

        Dump();
    }

    // デキューの常時監視をスタート
    auto th1 = std::thread([] { workConsume(); });

    // 無限ループ
    for (;;)
    {
        std::string message = rotationBuffer::getMessage();
        if ("" != message)
        {
            // 末尾に daze を付ける。
            message += "daze";

            // エンキューする
            enqueue( message);
        }
        std::this_thread::sleep_for(std::chrono::milliseconds(20));
    }

    // このプログラムは、自分では接続を切らない。

    // th1 スレッドの終了を待つ
    th1.join();
    return 0;
}
root@tk2-217-18401:/home/★user/shogi/csharp_service# ./tamesi34_cs.exe
削除したいキューがあれば名前を、無ければ空文字列を入れろだぜ☆(^~^)
キュー名を入力    : キューを削除します
空文字列で[Enter] : 次のステップへ進む
Name or empty ? >
エンキュー先のメッセージ・キューの名前を入れろだぜ☆(^~^)
Queue name? > 1116
エンキュー先のメッセージ・キューの寿命を、足し算して答えろだぜ☆(^~^)
(1) durable    : RabbitMQが止まってもキューを残す
(2) autodelete : コンシューマーが1人も接続していなかったら消す
(4) passive    : キューが存在するかどうかチェックするだけ。中身見ない時これ
(8) exclusive  : この接続でだけ使える。この接続が切れたら消す
Number ? > 1
デキュー先のメッセージ・キューの名前を入れろだぜ☆(^~^)
Queue name? > 1117
デキュー先のメッセージ・キューの寿命を、足し算して答えろだぜ☆(^~^)
(1) durable    : RabbitMQが止まってもキューを残す
(2) autodelete : コンシューマーが1人も接続していなかったら消す
(4) passive    : キューが存在するかどうかチェックするだけ。中身見ない時これ
(8) exclusive  : この接続でだけ使える。この接続が切れたら消す
Number ? > 3
tamesi34_cs.cs Dump
    name_queues         [ENQUEUE_INDEX]    =[1116]
    lifeSpan_queues     [ENQUEUE_INDEX]    =[Durable]
    durable_lifeSpans   [ENQUEUE_INDEX]    =[True]
    autodelete_lifeSpans[ENQUEUE_INDEX]    =[False]
    passive_lifeSpans   [ENQUEUE_INDEX]    =[False]
    exclusive_lifeSpans [ENQUEUE_INDEX]    =[False]
    ----
    name_queues         [DEQUEUE_INDEX]    =[1117]
    lifeSpan_queues     [DEQUEUE_INDEX]    =[Durable, Autodelete]
    durable_lifeSpans   [DEQUEUE_INDEX]    =[True]
    autodelete_lifeSpans[DEQUEUE_INDEX]    =[True]
    passive_lifeSpans   [DEQUEUE_INDEX]    =[False]
    exclusive_lifeSpans [DEQUEUE_INDEX]    =[False]
    ----
    name_queues         [DELETEQUEUE_INDEX]=[]
    lifeSpan_queues     [DELETEQUEUE_INDEX]=[0]
    durable_lifeSpans   [DELETEQUEUE_INDEX]=[False]
    autodelete_lifeSpans[DELETEQUEUE_INDEX]=[False]
    passive_lifeSpans   [DELETEQUEUE_INDEX]=[False]
    exclusive_lifeSpans [DELETEQUEUE_INDEX]=[False]
    ----

(tamesi34_cs.cs?) GetChannel index = [1]
    name_queues[index] = [1117]
    passive_lifeSpans[index] = [False]
    durable_lifeSpans[index] = [True]
    exclusive_lifeSpans[index] = [False]
    autodelete_lifeSpans[index] = [True]
    nowait は仮に false 固定
    arguments は仮に null 固定
終了するときは[Ctrl]+[C]キーを押せだぜ☆(^~^)
エンキューするときはメッセージを打ち込んで[Enter]キーを押せだぜ☆(^◇^)
Enqueue? > usi
tamesi34_cs.cs Dump
    name_queues         [ENQUEUE_INDEX]    =[1116]
    lifeSpan_queues     [ENQUEUE_INDEX]    =[Durable]
    durable_lifeSpans   [ENQUEUE_INDEX]    =[True]
    autodelete_lifeSpans[ENQUEUE_INDEX]    =[False]
    passive_lifeSpans   [ENQUEUE_INDEX]    =[False]
    exclusive_lifeSpans [ENQUEUE_INDEX]    =[False]
    ----
    name_queues         [DEQUEUE_INDEX]    =[1117]
    lifeSpan_queues     [DEQUEUE_INDEX]    =[Durable, Autodelete]
    durable_lifeSpans   [DEQUEUE_INDEX]    =[True]
    autodelete_lifeSpans[DEQUEUE_INDEX]    =[True]
    passive_lifeSpans   [DEQUEUE_INDEX]    =[False]
    exclusive_lifeSpans [DEQUEUE_INDEX]    =[False]
    ----
    name_queues         [DELETEQUEUE_INDEX]=[]
    lifeSpan_queues     [DELETEQUEUE_INDEX]=[0]
    durable_lifeSpans   [DELETEQUEUE_INDEX]=[False]
    autodelete_lifeSpans[DELETEQUEUE_INDEX]=[False]
    passive_lifeSpans   [DELETEQUEUE_INDEX]=[False]
    exclusive_lifeSpans [DELETEQUEUE_INDEX]=[False]
    ----

(tamesi34_cs.cs?) GetChannel index = [0]
    name_queues[index] = [1116]
    passive_lifeSpans[index] = [False]
    durable_lifeSpans[index] = [True]
    exclusive_lifeSpans[index] = [False]
    autodelete_lifeSpans[index] = [False]
    nowait は仮に false 固定
    arguments は仮に null 固定
 Enqueue(^q^) usi
Enqueue? >

動かね。落ちてるし。もっかい起動。

root@tk2-217-18401:/home/★user/shogi/cpp_service# Welcome! AMQP::durable=[1] AMQP::autodelete=[2] AMQP::passive=[8] AMQP::exclusive=[512]
jobs
[1]+  Segmentation fault      ./tamesi35a2_cpp.exe --enqueue 1117 durable autodelete --dequeue 1116 durable autodelete 2> ./tamesi35a2_cpp.err.log

セグメンテーション・フォールトって何だぜ?

「Running application ends with “Segmentation Fault”」(UNIX & LINUX)
http://unix.stackexchange.com/questions/132192/running-application-ends-with-segmentation-fault

プログラムをコメントアウトしても これが出る。

# ./tamesi35a2_cpp.exe --enqueue 1117 durable autodelete --dequeue 1116 durable autodelete 2> ./tamesi35a2_cpp.err.log &
# ./tamesi35a2_cpp.exe

こうすると 違うプログラムの結果が出るんだが。

                // 解析器
                std::string a;
                while (!data.eof()) {
                        data >> a;
                        if ("--enqueue" == a.substr(0, 2))
                        {
                                m0 = 0;
                                titles[m0] = a.substr(2); // 最初の2文字「--」の次から
                                lifespans.push_back(std::vector<std::string>()); // リストの中にリストを準備
                        }
                        else if ("--dequeue" == a.substr(0, 2))
                        {
                                m0 = 1;
                                titles[m0] = a.substr(2); // 最初の2文字「--」の次から
                                lifespans.push_back(std::vector<std::string>()); // リストの中にリストを準備
                        }
                        else { lifespans[m0].push_back(a); } // 要素数-1 で最後の要素

                        std::cout << "a=[" << a << "]" << std::endl;
                }

この直前まで動く。この中で セグメンテーション・フォールトしてるようだ。

あー。

# ./tamesi35a2_cpp.exe

引数付けずに コマンド叩いていたぜ。

int main(int argc, char* argv[])
{
    std::cout << "(^q^)Welcome! AMQP::durable=[" << AMQP::durable << "] AMQP::autodelete=[" << AMQP::autodelete << "] AMQP::passive=[" << AMQP::passive << "] AMQP::exclusive=[" << AMQP::exclusive << "]" << std::endl;

    // 引数の解析
    {
        // プログラム名を省き、コマンドライン引数だけをつなげる。
        std::string cmdArg;
        for (int i = 1; i < argc; ++i)
        {
            cmdArg += std::string(argv[i]) + " ";
        }
        std::istringstream data(cmdArg);

        // 与件
        // 「--enqueue 1117 durable autodelete --dequeue 1116 durable autodelete」
        // 寿命は可変個数設定可能「durable」「autodelete」「passive」「exclusive」

        // 受け皿
        std::string queueNames[2] = {}; // 結果はこれらの配列に入れる
        std::vector<std::string> lifespans[2] = {};

        // 記憶
        int m0 = -1; // 0:enqueue, 1:dequeue

        // 解析器
        std::string a;
        while (!data.eof()) {
            data >> a;
            std::cout << "a=[" << a << "]" << std::endl;

            if (2<a.size() && "--enqueue" == a.substr(0, 2))
            {
                m0 = 0;

                data >> a;
                queueNames[m0] = a; // キュー名
                lifespans[m0] = std::vector<std::string>();// 配列の中にリストを準備
            }
            else if (2<a.size() && "--dequeue" == a.substr(0, 2))
            {
                m0 = 1;

                data >> a;
                queueNames[m0] = a; // キュー名
                lifespans[m0] = std::vector<std::string>();// 配列の中にリストを準備
            }
            else { lifespans[m0].push_back(a); } // 要素数-1 で最後の要素
        }

        if ("" == queueNames[0] || "" == queueNames[1]) {
            std::cerr << "コマンドライン引数の「--enqueue キュー名 寿命」「--dequeue キュー名 寿命」を漏れなく指定してください。例: --enqueue 1117 durable autodelete --dequeue 1116 durable autodelete";
            exit(1);
        }
        // エンキュー
        m0 = 0;
        name_queues[ENQUEUE_INDEX] = queueNames[m0];
        lifeSpan_queues[ENQUEUE_INDEX] = (LifeSpanType)0;
        {
            for (std::string lifespan : lifespans[m0])
            {
                lifeSpan_queues[ENQUEUE_INDEX] = (LifeSpanType)((int)lifeSpan_queues[ENQUEUE_INDEX] | (int)LifeSpanString_To_Enum(lifespan));
            }
        }
        m0 = 1;
        name_queues[DEQUEUE_INDEX] = queueNames[m0];
        {
            for (std::string lifespan : lifespans[m0])
            {
                lifeSpan_queues[DEQUEUE_INDEX] = (LifeSpanType)((int)lifeSpan_queues[DEQUEUE_INDEX] | (int)LifeSpanString_To_Enum(lifespan));
            }
        }

        Dump();
    }

    // デキューの常時監視をスタート
    auto th1 = std::thread([] { workConsume(); });

    // 無限ループ
    for (;;)
    {
        std::string message = rotationBuffer::getMessage();
        if ("" != message)
        {
            // 末尾に daze を付ける。
            message += "daze";

            // エンキューする
            enqueue( message);
        }
        std::this_thread::sleep_for(std::chrono::milliseconds(20));
    }

    // このプログラムは、自分では接続を切らない。

    // th1 スレッドの終了を待つ
    th1.join();

    std::cout << "(^q^)Finished!" << std::endl;
    return 0;
}

こう書いてもまだ セグメンテーション・フォールト。

じゃあ、こうか。

int main(int argc, char* argv[])
{
    std::cout << "(^q^)Welcome! AMQP::durable=[" << AMQP::durable << "] AMQP::autodelete=[" << AMQP::autodelete << "] AMQP::passive=[" << AMQP::passive << "] AMQP::exclusive=[" << AMQP::exclusive << "]" << std::endl;

    // 引数の解析
    if(0<argc)
    {
        // プログラム名を省き、コマンドライン引数だけをつなげる。
        std::string cmdArg;
        for (int i = 1; i < argc; ++i)
        {
            cmdArg += std::string(argv[i]) + " ";
        }
        std::istringstream data(cmdArg);

        // 与件
        // 「--enqueue 1117 durable autodelete --dequeue 1116 durable autodelete」
        // 寿命は可変個数設定可能「durable」「autodelete」「passive」「exclusive」

        // 受け皿
        std::string queueNames[2] = {}; // 結果はこれらの配列に入れる
        std::vector<std::string> lifespans[2] = {};

        // 記憶
        int m0 = -1; // 0:enqueue, 1:dequeue

        // 解析器
        std::string a;
        while (!data.eof()) {
            data >> a;
            std::cout << "a=[" << a << "]" << std::endl;

            if (2<a.size() && "--enqueue" == a.substr(0, 2))
            {
                m0 = 0;

                data >> a;
                queueNames[m0] = a; // キュー名
                lifespans[m0] = std::vector<std::string>();// 配列の中にリストを準備
            }
            else if (2<a.size() && "--dequeue" == a.substr(0, 2))
            {
                m0 = 1;

                data >> a;
                queueNames[m0] = a; // キュー名
                lifespans[m0] = std::vector<std::string>();// 配列の中にリストを準備
            }
            else { lifespans[m0].push_back(a); } // 要素数-1 で最後の要素
        }

        if ("" == queueNames[0] || "" == queueNames[1]) {
            std::cerr << "コマンドライン引数の「--enqueue キュー名 寿命」「--dequeue キュー名 寿命」を漏れなく指定してください。例: --enqueue 1117 durable autodelete --dequeue 1116 durable autodelete";
            exit(1);
        }
        // エンキュー
        m0 = 0;
        name_queues[ENQUEUE_INDEX] = queueNames[m0];
        lifeSpan_queues[ENQUEUE_INDEX] = (LifeSpanType)0;
        {
            for (std::string lifespan : lifespans[m0])
            {
                lifeSpan_queues[ENQUEUE_INDEX] = (LifeSpanType)((int)lifeSpan_queues[ENQUEUE_INDEX] | (int)LifeSpanString_To_Enum(lifespan));
            }
        }
        m0 = 1;
        name_queues[DEQUEUE_INDEX] = queueNames[m0];
        {
            for (std::string lifespan : lifespans[m0])
            {
                lifeSpan_queues[DEQUEUE_INDEX] = (LifeSpanType)((int)lifeSpan_queues[DEQUEUE_INDEX] | (int)LifeSpanString_To_Enum(lifespan));
            }
        }

        Dump();
    }
    else
    {
        std::cerr << "コマンドライン引数を指定してください。例: --enqueue 1117 durable autodelete --dequeue 1116 durable autodelete";
        exit(1);
    }

    // デキューの常時監視をスタート
    auto th1 = std::thread([] { workConsume(); });

    // 無限ループ
    for (;;)
    {
        std::string message = rotationBuffer::getMessage();
        if ("" != message)
        {
            // 末尾に daze を付ける。
            message += "daze";

            // エンキューする
            enqueue( message);
        }
        std::this_thread::sleep_for(std::chrono::milliseconds(20));
    }

    // このプログラムは、自分では接続を切らない。

    // th1 スレッドの終了を待つ
    th1.join();

    std::cout << "(^q^)Finished!" << std::endl;
    return 0;
}
# ./tamesi35a2_cpp.exe
(^q^)Welcome! AMQP::durable=[1] AMQP::autodelete=[2] AMQP::passive=[8] AMQP::exclusive=[512]
a=[]
コマンドライン引数の「--enqueue キュー名 寿命」「--dequeue キュー名 寿命」を漏れなく指定してください。例: --enqueue 1117 durable autodelete --dequeue 1116 durable autodelete

これで警告を出しておこう。

# ./tamesi35a2_cpp.exe --enqueue 1117 durable autodelete --dequeue 1116 durable35a2_cpp.err.log &amesi
[1] 16535
root@tk2-217-18401:/home/★user/shogi/cpp_service# (^q^)Welcome! AMQP::durable=[1] AMQP::autodelete=[2] AMQP::passive=[8] AMQP::exclusive=[512]
a=[--enqueue]
a=[1117]
a=[durable]
a=[autodelete]
a=[--dequeue]
a=[1116]
a=[durable]
a=[autodelete]
a=[autodelete]

最後の2つが余計だな。

int main(int argc, char* argv[])
{
    std::cout << "(^q^)Welcome! AMQP::durable=[" << AMQP::durable << "] AMQP::autodelete=[" << AMQP::autodelete << "] AMQP::passive=[" << AMQP::passive << "] AMQP::exclusive=[" << AMQP::exclusive << "]" << std::endl;

    // 引数の解析
    if(0<argc)
    {
        // プログラム名を省き、コマンドライン引数だけをつなげる。
        std::string cmdArg;
        for (int i = 1; i < argc; ++i)
        {
            cmdArg += std::string(argv[i]) + " ";
        }
        std::cout << "(^q^)Welcome! cmdArg=[" << cmdArg << "]" << std::endl;
        std::istringstream data(cmdArg);

        // 与件
        // 「--enqueue 1117 durable autodelete --dequeue 1116 durable autodelete」
        // 寿命は可変個数設定可能「durable」「autodelete」「passive」「exclusive」

        // 受け皿
        std::string queueNames[2] = {}; // 結果はこれらの配列に入れる
        std::vector<std::string> lifespans[2] = {};

        // 記憶
        int m0 = -1; // 0:enqueue, 1:dequeue

        // 解析器
        std::string a;
        while (!data.eof()) {
            data >> a;
            std::cout << "a=[" << a << "]" << std::endl;

            if ("--enqueue" == a)
            {
                std::cout << "(^q^)A!" << std::endl;
                m0 = 0;

                data >> a;
                queueNames[m0] = a; // キュー名
                lifespans[m0] = std::vector<std::string>();// 配列の中にリストを準備
            }
            else if ("--dequeue" == a)
            {
                std::cout << "(^q^)B!" << std::endl;
                m0 = 1;

                data >> a;
                queueNames[m0] = a; // キュー名
                lifespans[m0] = std::vector<std::string>();// 配列の中にリストを準備
            }
            else
            {
                std::cout << "(^q^)C!" << std::endl;
                lifespans[m0].push_back(a);
            } // 要素数-1 で最後の要素
        }

        if ("" == queueNames[0] || "" == queueNames[1]) {
            std::cerr << "コマンドライン引数の「--enqueue キュー名 寿命」「--dequeue キュー名 寿命」を漏れなく指定してください。例: --enqueue 1117 durable autodelete --dequeue 1116 durable autodelete";
            exit(1);
        }
        // エンキュー
        m0 = 0;
        name_queues[ENQUEUE_INDEX] = queueNames[m0];
        lifeSpan_queues[ENQUEUE_INDEX] = (LifeSpanType)0;
        {
            for (std::string lifespan : lifespans[m0])
            {
                lifeSpan_queues[ENQUEUE_INDEX] = (LifeSpanType)((int)lifeSpan_queues[ENQUEUE_INDEX] | (int)LifeSpanString_To_Enum(lifespan));
            }
        }
        m0 = 1;
        name_queues[DEQUEUE_INDEX] = queueNames[m0];
        {
            for (std::string lifespan : lifespans[m0])
            {
                lifeSpan_queues[DEQUEUE_INDEX] = (LifeSpanType)((int)lifeSpan_queues[DEQUEUE_INDEX] | (int)LifeSpanString_To_Enum(lifespan));
            }
        }

        Dump();
    }
    else
    {
        std::cerr << "コマンドライン引数を指定してください。例: --enqueue 1117 durable autodelete --dequeue 1116 durable autodelete";
        exit(1);
    }

    // デキューの常時監視をスタート
    auto th1 = std::thread([] { workConsume(); });

    // 無限ループ
    for (;;)
    {
        std::string message = rotationBuffer::getMessage();
        if ("" != message)
        {
            // 末尾に daze を付ける。
            message += "daze";

            // エンキューする
            enqueue( message);
        }
        std::this_thread::sleep_for(std::chrono::milliseconds(20));
    }

    // このプログラムは、自分では接続を切らない。

    // th1 スレッドの終了を待つ
    th1.join();

    std::cout << "(^q^)Finished!" << std::endl;
    return 0;
}

プログラム間違えてる。

root@tk2-217-18401:/home/★user/shogi/cpp_service# (^q^)Welcome! AMQP::durable=[1] AMQP::autodelete=[2] AMQP::passive=[8] AMQP::exclusive=[512]
(^q^)Welcome! cmdArg=[--enqueue 1117 durable autodelete --dequeue 1116 durable autodelete ]
a=[--enqueue]
(^q^)A!
a=[durable]
(^q^)C!
a=[autodelete]
(^q^)C!
a=[--dequeue]
(^q^)B!
a=[durable]
(^q^)C!
a=[autodelete]
(^q^)C!
a=[autodelete]
(^q^)C!
*** Error in `./tamesi35a2_cpp.exe': realloc(): invalid next size: 0x00007f49678d6e60 ***
======= Backtrace: =========
/lib/x86_64-linux-gnu/libc.so.6(+0x777e5)[0x7f496736d7e5]
/lib/x86_64-linux-gnu/libc.so.6(+0x82a5a)[0x7f4967378a5a]
/lib/x86_64-linux-gnu/libc.so.6(+0x84ff9)[0x7f496737aff9]
/lib/x86_64-linux-gnu/libc.so.6(realloc+0x22f)[0x7f4967379d3f]
/usr/lib/x86_64-linux-gnu/libev.so.4(+0x3f2a)[0x7f49681d2f2a]
/usr/lib/x86_64-linux-gnu/libev.so.4(ev_io_start+0x10d)[0x7f49681d430d]
./tamesi35a2_cpp.exe[0x4206a5]
./tamesi35a2_cpp.exe[0x42081f]
/usr/lib/libamqpcpp.so.2.6(_ZN4AMQP11TcpResolverC1EPNS_13TcpConnectionERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEtPNS_10TcpHandlerE+0x113)[0x7f4967f90869]
/usr/lib/libamqpcpp.so.2.6(_ZN4AMQP13TcpConnectionC1EPNS_10TcpHandlerERKNS_7AddressE+0xa2)[0x7f4967f8e09c]
./tamesi35a2_cpp.exe[0x41ba70]
./tamesi35a2_cpp.exe[0x41bc47]
./tamesi35a2_cpp.exe[0x41e654]
./tamesi35a2_cpp.exe[0x41e5aa]
./tamesi35a2_cpp.exe[0x41e53a]
/usr/lib/x86_64-linux-gnu/libstdc++.so.6(+0xb8c80)[0x7f4967baac80]
/lib/x86_64-linux-gnu/libpthread.so.0(+0x76ba)[0x7f49676c66ba]
/lib/x86_64-linux-gnu/libc.so.6(clone+0x6d)[0x7f49673fc82d]
======= Memory map: ========
00400000-00433000 r-xp 00000000 fd:01 1573709                            /home/★user/shogi/cpp_service/tamesi35a2_cpp.exe
00633000-00634000 r--p 00033000 fd:01 1573709                            /home/★user/shogi/cpp_service/tamesi35a2_cpp.exe
00634000-00635000 rw-p 00034000 fd:01 1573709                            /home/★user/shogi/cpp_service/tamesi35a2_cpp.exe
00635000-00636000 rw-p 00000000 00:00 0
0113b000-0116d000 rw-p 00000000 00:00 0                                  [heap]
7f4960000000-7f4960021000 rw-p 00000000 00:00 0
7f4960021000-7f4964000000 ---p 00000000 00:00 0
7f49667ec000-7f49667ed000 ---p 00000000 00:00 0
7f49667ed000-7f4966fed000 rw-p 00000000 00:00 0                          [stack:16631]
7f4966fed000-7f49670f5000 r-xp 00000000 fd:01 787800                     /lib/x86_64-linux-gnu/libm-2.23.so
7f49670f5000-7f49672f4000 ---p 00108000 fd:01 787800                     /lib/x86_64-linux-gnu/libm-2.23.so
7f49672f4000-7f49672f5000 r--p 00107000 fd:01 787800                     /lib/x86_64-linux-gnu/libm-2.23.so
7f49672f5000-7f49672f6000 rw-p 00108000 fd:01 787800                     /lib/x86_64-linux-gnu/libm-2.23.so
7f49672f6000-7f49674b5000 r-xp 00000000 fd:01 787795                     /lib/x86_64-linux-gnu/libc-2.23.so
7f49674b5000-7f49676b5000 ---p 001bf000 fd:01 787795                     /lib/x86_64-linux-gnu/libc-2.23.so
7f49676b5000-7f49676b9000 r--p 001bf000 fd:01 787795                     /lib/x86_64-linux-gnu/libc-2.23.so
7f49676b9000-7f49676bb000 rw-p 001c3000 fd:01 787795                     /lib/x86_64-linux-gnu/libc-2.23.so
7f49676bb000-7f49676bf000 rw-p 00000000 00:00 0
7f49676bf000-7f49676d7000 r-xp 00000000 fd:01 787801                     /lib/x86_64-linux-gnu/libpthread-2.23.so
7f49676d7000-7f49678d6000 ---p 00018000 fd:01 787801                     /lib/x86_64-linux-gnu/libpthread-2.23.so
7f49678d6000-7f49678d7000 r--p 00017000 fd:01 787801                     /lib/x86_64-linux-gnu/libpthread-2.23.so
7f49678d7000-7f49678d8000 rw-p 00018000 fd:01 787801                     /lib/x86_64-linux-gnu/libpthread-2.23.so
7f49678d8000-7f49678dc000 rw-p 00000000 00:00 0
7f49678dc000-7f49678f2000 r-xp 00000000 fd:01 786610                     /lib/x86_64-linux-gnu/libgcc_s.so.1
7f49678f2000-7f4967af1000 ---p 00016000 fd:01 786610                     /lib/x86_64-linux-gnu/libgcc_s.so.1
7f4967af1000-7f4967af2000 rw-p 00015000 fd:01 786610                     /lib/x86_64-linux-gnu/libgcc_s.so.1
7f4967af2000-7f4967c64000 r-xp 00000000 fd:01 1050075                    /usr/lib/x86_64-linux-gnu/libstdc++.so.6.0.21
7f4967c64000-7f4967e64000 ---p 00172000 fd:01 1050075                    /usr/lib/x86_64-linux-gnu/libstdc++.so.6.0.21
7f4967e64000-7f4967e6e000 r--p 00172000 fd:01 1050075                    /usr/lib/x86_64-linux-gnu/libstdc++.so.6.0.21
7f4967e6e000-7f4967e70000 rw-p 0017c000 fd:01 1050075                    /usr/lib/x86_64-linux-gnu/libstdc++.so.6.0.21
7f4967e70000-7f4967e74000 rw-p 00000000 00:00 0
7f4967e74000-7f4967fc2000 r-xp 00000000 fd:01 1063316                    /usr/lib/libamqpcpp.so.2.6.2
7f4967fc2000-7f49681c2000 ---p 0014e000 fd:01 1063316                    /usr/lib/libamqpcpp.so.2.6.2
7f49681c2000-7f49681c8000 r--p 0014e000 fd:01 1063316                    /usr/lib/libamqpcpp.so.2.6.2
7f49681c8000-7f49681cf000 rw-p 00154000 fd:01 1063316                    /usr/lib/libamqpcpp.so.2.6.2
7f49681cf000-7f49681dc000 r-xp 00000000 fd:01 1063327                    /usr/lib/x86_64-linux-gnu/libev.so.4.0.0
7f49681dc000-7f49683db000 ---p 0000d000 fd:01 1063327                    /usr/lib/x86_64-linux-gnu/libev.so.4.0.0
7f49683db000-7f49683dc000 r--p 0000c000 fd:01 1063327                    /usr/lib/x86_64-linux-gnu/libev.so.4.0.0
7f49683dc000-7f49683dd000 rw-p 0000d000 fd:01 1063327                    /usr/lib/x86_64-linux-gnu/libev.so.4.0.0
7f49683dd000-7f4968403000 r-xp 00000000 fd:01 787782                     /lib/x86_64-linux-gnu/ld-2.23.so
7f49685ee000-7f49685f4000 rw-p 00000000 00:00 0
7f49685ff000-7f4968602000 rw-p 00000000 00:00 0
7f4968602000-7f4968603000 r--p 00025000 fd:01 787782                     /lib/x86_64-linux-gnu/ld-2.23.so
7f4968603000-7f4968604000 rw-p 00026000 fd:01 787782                     /lib/x86_64-linux-gnu/ld-2.23.so
7f4968604000-7f4968605000 rw-p 00000000 00:00 0
7ffc69d66000-7ffc69d87000 rw-p 00000000 00:00 0                          [stack]
7ffc69df6000-7ffc69df8000 r-xp 00000000 00:00 0                          [vdso]
ffffffffff600000-ffffffffff601000 r-xp 00000000 00:00 0                  [vsyscall]
^C
[1]+  Aborted                 ./tamesi35a2_cpp.exe --enqueue 1117 durable autodelete --dequeue 1116 durable autodelete 2> ./tamesi35a2_cpp.err.log
        std::string a;
        while (!data.eof()) {
            a = "(^q^)error!";
            data >> a;
            std::cout << "a=[" << a << "]" << std::endl;

文字列の終端を取れていないようだ。

root@tk2-217-18401:~# ls
tamesi35a2_cs.err.log  tamesi35a2_cs.out.log

エラーログが、ルート・フォルダに吐かれてるんじゃないか?

# ./tamesi35a2_cpp.exe --enqueue 1117 durable autodelete --dequeue 1116 durable autodelete 2> ./tamesi35a2_cpp.err.log &
[1] 17059

# (^q^)Welcome! AMQP::durable=[1] AMQP::autodelete=[2] AMQP::passive=[8] AMQP::exclusive=[512]
(^q^)Welcome! cmdArg=[--enqueue 1117 durable autodelete --dequeue 1116 durable autodelete ]
(^q^)Welcome! data.str()=[--enqueue 1117 durable autodelete --dequeue 1116 durable autodelete ]
a=[--enqueue]
(^q^)A!
a=[durable]
(^q^)C!
a=[autodelete]
(^q^)C!
a=[--dequeue]
(^q^)B!
a=[durable]
(^q^)C!
a=[autodelete]
(^q^)C!
a=[(^q^)error! data.str()=[--enqueue 1117 durable autodelete --dequeue 1116 durable autodelete ]]
(^q^)C!

最後の動きは何だろう?

「Why doesn't the istringstream eof flag become true when successfully converting a boolean string value to a bool?」(stack overflow)
http://stackoverflow.com/questions/24219807/why-doesnt-the-istringstream-eof-flag-become-true-when-successfully-converting

「!data.eof()」が g++ だと動いてないんじゃないか?

「std::istream::tellg」(cplusplus.com)
http://www.cplusplus.com/reference/istream/istream/tellg/

g++ だと「-1 != data.tellg()」もダメみたいだが。

浮かむ瀬を見習うと

while (data >> a) {

でいいようだ。

# (^q^)Welcome! AMQP::durable=[1] AMQP::autodelete=[2] AMQP::passive=[8] AMQP::exclusive=[512]
(^q^)Welcome! cmdArg=[--enqueue 1117 durable autodelete --dequeue 1116 durable autodelete ]
(^q^)Welcome! data.str()=[--enqueue 1117 durable autodelete --dequeue 1116 durable autodelete ]
a=[(^q^)error! data.str()=[--enqueue 1117 durable autodelete --dequeue 1116 durable autodelete ]]
(^q^)C!

うーむ?

# (^q^)Welcome! AMQP::durable=[1                    ] AMQP::autodelete=[2] AMQP::passive=[8] AMQP::exclusive=[512]
(^q^)cmdArg=[--enqueue 1117 durable autodelete --dequeue 1116 durable autodelete                     ]
(^q^)data.str()=[--enqueue 1117 durable autodelete --dequeue 1116 durable autode                    lete ]
a=[--enqueue]
(^q^)A!
a=[durable]
(^q^)C!
a=[autodelete]
(^q^)C!
a=[--dequeue]
(^q^)B!
a=[durable]
(^q^)C!
a=[autodelete]
(^q^)C!
*** Error in `./tamesi35a2_cpp.exe': realloc(): invalid next size: 0x00007f6141d                    21e60 ***
======= Backtrace: =========
/lib/x86_64-linux-gnu/libc.so.6(+0x777e5)[0x7f61417b87e5]
/lib/x86_64-linux-gnu/libc.so.6(+0x82a5a)[0x7f61417c3a5a]
/lib/x86_64-linux-gnu/libc.so.6(+0x84ff9)[0x7f61417c5ff9]
/lib/x86_64-linux-gnu/libc.so.6(realloc+0x22f)[0x7f61417c4d3f]
/usr/lib/x86_64-linux-gnu/libev.so.4(+0x3f2a)[0x7f614261df2a]

うーむ?

int main(int argc, char* argv[])
{
    std::cout << "(^q^)Welcome! AMQP::durable=[" << AMQP::durable << "] AMQP::autodelete=[" << AMQP::autodelete << "] AMQP::passive=[" << AMQP::passive << "] AMQP::exclusive=[" << AMQP::exclusive << "]" << std::endl;

    // 引数の解析
    if(0<argc)
    {
        // プログラム名を省き、コマンドライン引数だけをつなげる。
        std::string cmdArg;
        for (int i = 1; i < argc; ++i)
        {
            cmdArg += std::string(argv[i]) + " ";
        }
        std::cout << "(^q^)cmdArg=[" << cmdArg << "]" << std::endl;
        std::istringstream data(cmdArg);
        //data >> std::skipws;
        std::cout << "(^q^)data.str()=[" << data.str() << "]" << std::endl;

        // 与件
        // 「--enqueue 1117 durable autodelete --dequeue 1116 durable autodelete」
        // 寿命は可変個数設定可能「durable」「autodelete」「passive」「exclusive」

        // 受け皿
        std::string queueNames[2] = {}; // 結果はこれらの配列に入れる
        std::vector<std::string> lifespans[2] = {};

        // 記憶
        int m0 = -1; // 0:enqueue, 1:dequeue

        // 解析器
        std::string a;
        while (data >> a) {
            std::cout << "(^_^)a0=[" << a << "]" << std::endl;

            if ("--enqueue" == a)
            {
                std::cout << "(^q^)A!" << std::endl;
                m0 = 0;

                if (!(data >> a)) {
                    break;
                }
                std::cout << "(^_^)a1=[" << a << "]" << std::endl;

                queueNames[m0] = a; // キュー名
                lifespans[m0] = std::vector<std::string>();// 配列の中にリストを準備
            }
            else if ("--dequeue" == a)
            {
                std::cout << "(^q^)B!" << std::endl;
                m0 = 1;

                if (!(data >> a)) {
                    break;
                }
                std::cout << "(^_^)a2=[" << a << "]" << std::endl;

                queueNames[m0] = a; // キュー名
                lifespans[m0] = std::vector<std::string>();// 配列の中にリストを準備
            }
            else
            {
                std::cout << "(^q^)C!" << std::endl;
                lifespans[m0].push_back(a);
            } // 要素数-1 で最後の要素
        }

        if ("" == queueNames[0] || "" == queueNames[1]) {
            std::cerr << "コマンドライン引数の「--enqueue キュー名 寿命」「--dequeue キュー名 寿命」を漏れなく指定してください。例: --enqueue 1117 durable autodelete --dequeue 1116 durable autodelete";
            exit(1);
        }
        // エンキュー
        m0 = 0;
        name_queues[ENQUEUE_INDEX] = queueNames[m0];
        lifeSpan_queues[ENQUEUE_INDEX] = (LifeSpanType)0;
        {
            for (std::string lifespan : lifespans[m0])
            {
                lifeSpan_queues[ENQUEUE_INDEX] = (LifeSpanType)((int)lifeSpan_queues[ENQUEUE_INDEX] | (int)LifeSpanString_To_Enum(lifespan));
            }
        }
        m0 = 1;
        name_queues[DEQUEUE_INDEX] = queueNames[m0];
        {
            for (std::string lifespan : lifespans[m0])
            {
                lifeSpan_queues[DEQUEUE_INDEX] = (LifeSpanType)((int)lifeSpan_queues[DEQUEUE_INDEX] | (int)LifeSpanString_To_Enum(lifespan));
            }
        }

        Dump();
    }
    else
    {
        std::cerr << "コマンドライン引数を指定してください。例: --enqueue 1117 durable autodelete --dequeue 1116 durable autodelete";
        exit(1);
    }

    // デキューの常時監視をスタート
    auto th1 = std::thread([] { workConsume(); });

    // 無限ループ
    for (;;)
    {
        std::string message = rotationBuffer::getMessage();
        if ("" != message)
        {
            // 末尾に daze を付ける。
            message += "daze";

            // エンキューする
            enqueue( message);
        }
        std::this_thread::sleep_for(std::chrono::milliseconds(20));
    }

    // このプログラムは、自分では接続を切らない。

    // th1 スレッドの終了を待つ
    th1.join();

    std::cout << "(^q^)Finished!" << std::endl;
    return 0;
}

こう書いて、

# ./tamesi35a2_cpp.exe --enqueue 1117 durable --dequeue 1116 durable autodelete 2> ./tamesi35a2_cpp.err.log &
[1] 17696
root@tk2-217-18401:/home/★user/shogi/cpp_service# (^q^)Welcome! AMQP::durable=[1] AMQP::autodelete=[2] AMQP::passive=[8] AMQP::exclusive=[512]
(^q^)cmdArg=[--enqueue 1117 durable --dequeue 1116 durable autodelete ]
(^q^)data.str()=[--enqueue 1117 durable --dequeue 1116 durable autodelete ]
(^_^)a0=[--enqueue]
(^q^)A!
(^_^)a1=[1117]
(^_^)a0=[durable]
(^q^)C!
(^_^)a0=[--dequeue]
(^q^)B!
(^_^)a2=[1116]
(^_^)a0=[durable]
(^q^)C!
(^_^)a0=[autodelete]
(^q^)C!
*** Error in `./tamesi35a2_cpp.exe': realloc(): invalid next size: 0x00007fcd66751e60 ***
======= Backtrace: =========
/lib/x86_64-linux-gnu/libc.so.6(+0x777e5)[0x7fcd661e87e5]
/lib/x86_64-linux-gnu/libc.so.6(+0x82a5a)[0x7fcd661f3a5a]
/lib/x86_64-linux-gnu/libc.so.6(+0x84ff9)[0x7fcd661f5ff9]
/lib/x86_64-linux-gnu/libc.so.6(realloc+0x22f)[0x7fcd661f4d3f]
/usr/lib/x86_64-linux-gnu/libev.so.4(+0x3f2a)[0x7fcd6704df2a]
/usr/lib/x86_64-linux-gnu/libev.so.4(ev_io_start+0x10d)[0x7fcd6704f30d]
./tamesi35a2_cpp.exe[0x4208cf]
./tamesi35a2_cpp.exe[0x420a49]
/usr/lib/libamqpcpp.so.2.6(_ZN4AMQP11TcpResolverC1EPNS_13TcpConnectionERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEtPNS_10TcpHandlerE+0x113)[0x7fcd66e0b869]
/usr/lib/libamqpcpp.so.2.6(_ZN4AMQP13TcpConnectionC1EPNS_10TcpHandlerERKNS_7AddressE+0xa2)[0x7fcd66e0909c]
./tamesi35a2_cpp.exe[0x41bb60]
./tamesi35a2_cpp.exe[0x41bd37]
./tamesi35a2_cpp.exe[0x41e87e]
./tamesi35a2_cpp.exe[0x41e7d4]
./tamesi35a2_cpp.exe[0x41e764]
/usr/lib/x86_64-linux-gnu/libstdc++.so.6(+0xb8c80)[0x7fcd66a25c80]
/lib/x86_64-linux-gnu/libpthread.so.0(+0x76ba)[0x7fcd665416ba]
/lib/x86_64-linux-gnu/libc.so.6(clone+0x6d)[0x7fcd6627782d]
======= Memory map: ========
00400000-00434000 r-xp 00000000 fd:01 1573709                            /home/★user/shogi/cpp_service/tamesi35a2_cpp.exe
00633000-00634000 r--p 00033000 fd:01 1573709                            /home/★user/shogi/cpp_service/tamesi35a2_cpp.exe
00634000-00635000 rw-p 00034000 fd:01 1573709                            /home/★user/shogi/cpp_service/tamesi35a2_cpp.exe
00635000-00636000 rw-p 00000000 00:00 0
0089e000-008d0000 rw-p 00000000 00:00 0                                  [heap]
7fcd60000000-7fcd60021000 rw-p 00000000 00:00 0
7fcd60021000-7fcd64000000 ---p 00000000 00:00 0
7fcd65667000-7fcd65668000 ---p 00000000 00:00 0
7fcd65668000-7fcd65e68000 rw-p 00000000 00:00 0                          [stack:17697]
7fcd65e68000-7fcd65f70000 r-xp 00000000 fd:01 787800                     /lib/x86_64-linux-gnu/libm-2.23.so
7fcd65f70000-7fcd6616f000 ---p 00108000 fd:01 787800                     /lib/x86_64-linux-gnu/libm-2.23.so
7fcd6616f000-7fcd66170000 r--p 00107000 fd:01 787800                     /lib/x86_64-linux-gnu/libm-2.23.so
7fcd66170000-7fcd66171000 rw-p 00108000 fd:01 787800                     /lib/x86_64-linux-gnu/libm-2.23.so
7fcd66171000-7fcd66330000 r-xp 00000000 fd:01 787795                     /lib/x86_64-linux-gnu/libc-2.23.so
7fcd66330000-7fcd66530000 ---p 001bf000 fd:01 787795                     /lib/x86_64-linux-gnu/libc-2.23.so
7fcd66530000-7fcd66534000 r--p 001bf000 fd:01 787795                     /lib/x86_64-linux-gnu/libc-2.23.so
7fcd66534000-7fcd66536000 rw-p 001c3000 fd:01 787795                     /lib/x86_64-linux-gnu/libc-2.23.so
7fcd66536000-7fcd6653a000 rw-p 00000000 00:00 0
7fcd6653a000-7fcd66552000 r-xp 00000000 fd:01 787801                     /lib/x86_64-linux-gnu/libpthread-2.23.so
7fcd66552000-7fcd66751000 ---p 00018000 fd:01 787801                     /lib/x86_64-linux-gnu/libpthread-2.23.so
7fcd66751000-7fcd66752000 r--p 00017000 fd:01 787801                     /lib/x86_64-linux-gnu/libpthread-2.23.so
7fcd66752000-7fcd66753000 rw-p 00018000 fd:01 787801                     /lib/x86_64-linux-gnu/libpthread-2.23.so
7fcd66753000-7fcd66757000 rw-p 00000000 00:00 0
7fcd66757000-7fcd6676d000 r-xp 00000000 fd:01 786610                     /lib/x86_64-linux-gnu/libgcc_s.so.1
7fcd6676d000-7fcd6696c000 ---p 00016000 fd:01 786610                     /lib/x86_64-linux-gnu/libgcc_s.so.1
7fcd6696c000-7fcd6696d000 rw-p 00015000 fd:01 786610                     /lib/x86_64-linux-gnu/libgcc_s.so.1
7fcd6696d000-7fcd66adf000 r-xp 00000000 fd:01 1050075                    /usr/lib/x86_64-linux-gnu/libstdc++.so.6.0.21
7fcd66adf000-7fcd66cdf000 ---p 00172000 fd:01 1050075                    /usr/lib/x86_64-linux-gnu/libstdc++.so.6.0.21
7fcd66cdf000-7fcd66ce9000 r--p 00172000 fd:01 1050075                    /usr/lib/x86_64-linux-gnu/libstdc++.so.6.0.21
7fcd66ce9000-7fcd66ceb000 rw-p 0017c000 fd:01 1050075                    /usr/lib/x86_64-linux-gnu/libstdc++.so.6.0.21
7fcd66ceb000-7fcd66cef000 rw-p 00000000 00:00 0
7fcd66cef000-7fcd66e3d000 r-xp 00000000 fd:01 1063316                    /usr/lib/libamqpcpp.so.2.6.2
7fcd66e3d000-7fcd6703d000 ---p 0014e000 fd:01 1063316                    /usr/lib/libamqpcpp.so.2.6.2
7fcd6703d000-7fcd67043000 r--p 0014e000 fd:01 1063316                    /usr/lib/libamqpcpp.so.2.6.2
7fcd67043000-7fcd6704a000 rw-p 00154000 fd:01 1063316                    /usr/lib/libamqpcpp.so.2.6.2
7fcd6704a000-7fcd67057000 r-xp 00000000 fd:01 1063327                    /usr/lib/x86_64-linux-gnu/libev.so.4.0.0
7fcd67057000-7fcd67256000 ---p 0000d000 fd:01 1063327                    /usr/lib/x86_64-linux-gnu/libev.so.4.0.0
7fcd67256000-7fcd67257000 r--p 0000c000 fd:01 1063327                    /usr/lib/x86_64-linux-gnu/libev.so.4.0.0
7fcd67257000-7fcd67258000 rw-p 0000d000 fd:01 1063327                    /usr/lib/x86_64-linux-gnu/libev.so.4.0.0
7fcd67258000-7fcd6727e000 r-xp 00000000 fd:01 787782                     /lib/x86_64-linux-gnu/ld-2.23.so
7fcd67469000-7fcd6746f000 rw-p 00000000 00:00 0
7fcd6747a000-7fcd6747d000 rw-p 00000000 00:00 0
7fcd6747d000-7fcd6747e000 r--p 00025000 fd:01 787782                     /lib/x86_64-linux-gnu/ld-2.23.so
7fcd6747e000-7fcd6747f000 rw-p 00026000 fd:01 787782                     /lib/x86_64-linux-gnu/ld-2.23.so
7fcd6747f000-7fcd67480000 rw-p 00000000 00:00 0
7ffcd3118000-7ffcd3139000 rw-p 00000000 00:00 0                          [stack]
7ffcd31cb000-7ffcd31cd000 r-xp 00000000 00:00 0                          [vdso]
ffffffffff600000-ffffffffff601000 r-xp 00000000 00:00 0                  [vsyscall]c

スペース区切りなので、最後のスペースの後ろに ヌルでもあるんだろうか?

        std::string cmdArg;
        for (int i = 1; i < argc; ++i)
        {
            cmdArg += std::string(argv[i]);
            if (i < argc) {
                cmdArg += " ";
            }
        }

こう書き直してどうか?

int main(int argc, char* argv[])
{
    std::cout << "(^q^)Welcome! AMQP::durable=[" << AMQP::durable << "] AMQP::autodelete=[" << AMQP::autodelete << "] AMQP::passive=[" << AMQP::passive << "] AMQP::exclusive=[" << AMQP::exclusive << "]" << std::endl;

    // 引数の解析
    if(0<argc)
    {
        // プログラム名を省き、コマンドライン引数だけをつなげる。
        std::string cmdArg;
        for (int i = 1; i < argc; ++i)
        {
            cmdArg += std::string(argv[i]);
            if (i < argc) {
                cmdArg += " ";
            }
        }
        std::cout << "(^q^)cmdArg=[" << cmdArg << "]" << std::endl;
        std::istringstream data(cmdArg);
        //data >> std::skipws;
        std::cout << "(^q^)data.str()=[" << data.str() << "]" << std::endl;

        // 与件
        // 「--enqueue 1117 durable autodelete --dequeue 1116 durable autodelete」
        // 寿命は可変個数設定可能「durable」「autodelete」「passive」「exclusive」

        // 受け皿
        std::string queueNames[2] = {}; // 結果はこれらの配列に入れる
        std::vector<std::string> lifespans[2] = {};

        // 記憶
        int m0 = -1; // 0:enqueue, 1:dequeue

        // 解析器
        std::string a;
        while (data >> a) {
            std::cout << "(^_^)a0=[" << a << "]" << std::endl;

            if ("--enqueue" == a)
            {
                std::cout << "(^q^)A!" << std::endl;
                m0 = 0;

                if (!(data >> a)) {
                    break;
                }
                std::cout << "(^_^)a1=[" << a << "] m0=[" << m0 << "]" << std::endl;

                queueNames[m0] = a; // キュー名
                lifespans[m0] = std::vector<std::string>();// 配列の中にリストを準備
            }
            else if ("--dequeue" == a)
            {
                std::cout << "(^q^)B!" << std::endl;
                m0 = 1;

                if (!(data >> a)) {
                    break;
                }
                std::cout << "(^_^)a2=[" << a << "] m0=[" << m0 << "]" << std::endl;

                queueNames[m0] = a; // キュー名
                lifespans[m0] = std::vector<std::string>();// 配列の中にリストを準備
            }
            else
            {
                std::cout << "(^q^)C1! m0=[" << m0 << "]" << std::endl;
                lifespans[m0].push_back(a);
                std::cout << "(^q^)C2!" << std::endl;
            } // 要素数-1 で最後の要素
        }

        if ("" == queueNames[0] || "" == queueNames[1]) {
            std::cerr << "コマンドライン引数の「--enqueue キュー名 寿命」「--dequeue キュー名 寿命」を漏れなく指定してください。例: --enqueue 1117 durable autodelete --dequeue 1116 durable autodelete";
            exit(1);
        }
        // エンキュー
        m0 = 0;
        name_queues[ENQUEUE_INDEX] = queueNames[m0];
        lifeSpan_queues[ENQUEUE_INDEX] = (LifeSpanType)0;
        {
            for (std::string lifespan : lifespans[m0])
            {
                lifeSpan_queues[ENQUEUE_INDEX] = (LifeSpanType)((int)lifeSpan_queues[ENQUEUE_INDEX] | (int)LifeSpanString_To_Enum(lifespan));
            }
        }
        m0 = 1;
        name_queues[DEQUEUE_INDEX] = queueNames[m0];
        {
            for (std::string lifespan : lifespans[m0])
            {
                lifeSpan_queues[DEQUEUE_INDEX] = (LifeSpanType)((int)lifeSpan_queues[DEQUEUE_INDEX] | (int)LifeSpanString_To_Enum(lifespan));
            }
        }

        Dump();
    }
    else
    {
        std::cerr << "コマンドライン引数を指定してください。例: --enqueue 1117 durable autodelete --dequeue 1116 durable autodelete";
        exit(1);
    }

    // デキューの常時監視をスタート
    auto th1 = std::thread([] { workConsume(); });

    // 無限ループ
    for (;;)
    {
        std::string message = rotationBuffer::getMessage();
        if ("" != message)
        {
            // 末尾に daze を付ける。
            message += "daze";

            // エンキューする
            enqueue( message);
        }
        std::this_thread::sleep_for(std::chrono::milliseconds(20));
    }

    // このプログラムは、自分では接続を切らない。

    // th1 スレッドの終了を待つ
    th1.join();

    std::cout << "(^q^)Finished!" << std::endl;
    return 0;
}

こうして、

# (^q^)Welcome! AMQP::durable=[1] AMQP::autodelete=[2] AMQP::passive=[8] AMQP::exclusive=[512]
(^q^)cmdArg=[--enqueue 1117 durable --dequeue 1116 durable autodelete ]
(^q^)data.str()=[--enqueue 1117 durable --dequeue 1116 durable autodelete ]
(^_^)a0=[--enqueue]
(^q^)A!
(^_^)a1=[1117] m0=[0]
(^_^)a0=[durable]
(^q^)C1! m0=[0]
(^q^)C2!
(^_^)a0=[--dequeue]
(^q^)B!
(^_^)a2=[1116] m0=[1]
(^_^)a0=[durable]
(^q^)C1! m0=[1]
(^q^)C2!
(^_^)a0=[autodelete]
(^q^)C1! m0=[1]
(^q^)C2!
*** Error in `./tamesi35a2_cpp.exe': realloc(): invalid next size: 0x00007fc090b98e60 ***
======= Backtrace: =========
/lib/x86_64-linux-gnu/libc.so.6(+0x777e5)[0x7fc09062f7e5]
/lib/x86_64-linux-gnu/libc.so.6(+0x82a5a)[0x7fc09063aa5a]
/lib/x86_64-linux-gnu/libc.so.6(+0x84ff9)[0x7fc09063cff9]
/lib/x86_64-linux-gnu/libc.so.6(realloc+0x22f)[0x7fc09063bd3f]

うーむ?

// 解析器
                std::string a;
                while (data >> a) {
                        std::cout << "(^_^)a0=[" << a << "]" << std::endl;
                }
                std::cout << "(^-^)Loop end." << std::endl;

こう書くと、

# (^q^)Welcome! AMQP::durable=[1] AMQP::autodelete=[2] AMQP::passive=[8] AMQP::exclusive=[512]
(^q^)cmdArg=[--enqueue 1117 durable --dequeue 1116 durable autodelete ]
(^q^)data.str()=[--enqueue 1117 durable --dequeue 1116 durable autodelete ]
(^_^)a0=[--enqueue]
(^_^)a0=[1117]
(^_^)a0=[durable]
(^_^)a0=[--dequeue]
(^_^)a0=[1116]
(^_^)a0=[durable]
(^_^)a0=[autodelete]
(^-^)Loop end.
int main(int argc, char* argv[])
{
    std::cout << "(^q^)Welcome! AMQP::durable=[" << AMQP::durable << "] AMQP::autodelete=[" << AMQP::autodelete << "] AMQP::passive=[" << AMQP::passive << "] AMQP::exclusive=[" << AMQP::exclusive << "]" << std::endl;

    // 引数の解析
    if(0<argc)
    {
        // プログラム名を省き、コマンドライン引数だけをつなげる。
        std::string cmdArg;
        for (int i = 1; i < argc; ++i)
        {
            cmdArg += std::string(argv[i]);
            if (i < argc) {
                cmdArg += " ";
            }
        }
        std::cout << "(^q^)cmdArg=[" << cmdArg << "]" << std::endl;
        std::istringstream data(cmdArg);
        //data >> std::skipws;
        std::cout << "(^q^)data.str()=[" << data.str() << "]" << std::endl;

        // 与件
        // 「--enqueue 1117 durable autodelete --dequeue 1116 durable autodelete」
        // 寿命は可変個数設定可能「durable」「autodelete」「passive」「exclusive」

        // 受け皿
        std::string queueNames[2] = {}; // 結果はこれらの配列に入れる
        std::vector<std::string> lifespans[2] = {};

        // 記憶
        int m0 = -1; // 0:enqueue, 1:dequeue
        int m1 = -1; // lifespans index.

        // 解析器
        std::string a;
        while (data >> a) {
            std::cout << "(^_^)a0=[" << a << "]" << std::endl;

            if ("--enqueue" == a)
            {
                std::cout << "(^q^)A!" << std::endl;
                m0 = 0;
                m1 = -1;
            }
            else if ("--dequeue" == a)
            {
                std::cout << "(^q^)B!" << std::endl;
                m0 = 1;
                m1 = -1;
            }
            else if (-1 == m1 && 0 == m0) {
                std::cout << "(^q^)C!" << std::endl;
                queueNames[m0] = a; // キュー名
                lifespans[m0] = std::vector<std::string>();// 配列の中にリストを準備
                m1++;
            }
            else if (-1 == m1 && 1 == m0) {
                std::cout << "(^q^)D!" << std::endl;
                queueNames[m0] = a; // キュー名
                lifespans[m0] = std::vector<std::string>();// 配列の中にリストを準備
                m1++;
            }
            else
            {
                std::cout << "(^q^)E1! m0=[" << m0 << "] m1=[" << m1 << "]" << std::endl;
                lifespans[m0].push_back(a);
                std::cout << "(^q^)E2!" << std::endl;
            } // 要素数-1 で最後の要素
        }
        std::cout << "(^-^)Loop end." << std::endl;

        if ("" == queueNames[0] || "" == queueNames[1]) {
            std::cerr << "コマンドライン引数の「--enqueue キュー名 寿命」「--dequeue キュー名 寿命」を漏れなく指定してください。例: --enqueue 1117 durable autodelete --dequeue 1116 durable autodelete";
            exit(1);
        }
        // エンキュー
        m0 = 0;
        name_queues[ENQUEUE_INDEX] = queueNames[m0];
        lifeSpan_queues[ENQUEUE_INDEX] = (LifeSpanType)0;
        {
            for (std::string lifespan : lifespans[m0])
            {
                lifeSpan_queues[ENQUEUE_INDEX] = (LifeSpanType)((int)lifeSpan_queues[ENQUEUE_INDEX] | (int)LifeSpanString_To_Enum(lifespan));
            }
        }
        m0 = 1;
        name_queues[DEQUEUE_INDEX] = queueNames[m0];
        {
            for (std::string lifespan : lifespans[m0])
            {
                lifeSpan_queues[DEQUEUE_INDEX] = (LifeSpanType)((int)lifeSpan_queues[DEQUEUE_INDEX] | (int)LifeSpanString_To_Enum(lifespan));
            }
        }

        Dump();
    }
    else
    {
        std::cerr << "コマンドライン引数を指定してください。例: --enqueue 1117 durable autodelete --dequeue 1116 durable autodelete";
        exit(1);
    }

    // デキューの常時監視をスタート
    auto th1 = std::thread([] { workConsume(); });

    // 無限ループ
    for (;;)
    {
        std::string message = rotationBuffer::getMessage();
        if ("" != message)
        {
            // 末尾に daze を付ける。
            message += "daze";

            // エンキューする
            enqueue( message);
        }
        std::this_thread::sleep_for(std::chrono::milliseconds(20));
    }

    // このプログラムは、自分では接続を切らない。

    // th1 スレッドの終了を待つ
    th1.join();

    std::cout << "(^q^)Finished!" << std::endl;
    return 0;
}

こう書くと 途中では落ちなくなったが。

# (^q^)Welcome! AMQP::durable=[1] AMQP::autodelete=[2] AMQP::passive=[8] AMQP::exclusive=[512]
(^q^)cmdArg=[--enqueue 1117 durable --dequeue 1116 durable autodelete ]
(^q^)data.str()=[--enqueue 1117 durable --dequeue 1116 durable autodelete ]
(^_^)a0=[--enqueue]
(^q^)エンキュー!
(^_^)a0=[1117]
(^q^)エンキューのキュー名!
(^_^)a0=[durable]
(^q^)寿命! m0=[0] m1=[0]
(^q^)zyumyo-!
(^_^)a0=[--dequeue]
(^q^)デキュー!
(^_^)a0=[1116]
(^q^)デキューのキュー名!
(^_^)a0=[durable]
(^q^)寿命! m0=[1] m1=[0]
(^q^)zyumyo-!
(^_^)a0=[autodelete]
(^q^)寿命! m0=[1] m1=[0]
(^q^)zyumyo-!
(^-^)Loop end.
*** Error in `./tamesi35a2_cpp.exe': realloc(): invalid next size: 0x00007f5984d78e60 ***
======= Backtrace: =========
/lib/x86_64-linux-gnu/libc.so.6(+0x777e5)[0x7f598480f7e5]
/lib/x86_64-linux-gnu/libc.so.6(+0x82a5a)[0x7f598481aa5a]
/lib/x86_64-linux-gnu/libc.so.6(+0x84ff9)[0x7f598481cff9]
/lib/x86_64-linux-gnu/libc.so.6(realloc+0x22f)[0x7f598481bd3f]
(^q^)エンキューのキュー名=[1117]
(^q^)デキューのキュー名=[1116]
(^q^)エンキューの寿命の数=[1]
(^q^)デキューの寿命の数=[2]
            lifeSpan_queues[DEQUEUE_INDEX] = (LifeSpanType)0;

デキューの方にこれが足りないのでは?

コーディングのミスを発見したぜ。

    //struct ev_loop* loop;
    struct ev_loop* loop = EV_DEFAULT;

こうだろ。

//--------------------------------------------------------------------------------
// OS      : Windows10 : // このプログラムは動かない
//
// OS      : Ubuntu 16.04
// Library : libev
//         : Install   : Command  : sudo apt-get update
//                                : sudo apt-get install libev-dev
// Service : RabbitMQ
//         : Reference : Web site : Top page http://www.rabbitmq.com/
//         : Install   : Web site : Installing on Debian / Ubuntu http://www.rabbitmq.com/install-debian.html
//         : Manual    : Command  : man rabbitmqctl
//         : Start     : Command  : rabbitmq-server
//         : Stop      : Command  : rabbitmqctl stop
//         : Check     : Command  : rabbitmqctl status
//         :           : Command  : rabbitmqctl list_queues
// Library : AMQP-CPP
//         : Reference : Web site : AMQP-CPP README.md https://github.com/CopernicaMarketingSoftware/AMQP-CPP
//         : Reference : Web site : QueueDeclare http://docs.spring.io/spring-amqp-net/docs/1.0.x/api/html/Spring.Messaging.Amqp.Rabbit~Spring.Messaging.Amqp.Rabbit.Connection.CachedModel~QueueDeclare(String,Boolean,Boolean,Boolean,Boolean,Boolean,IDictionary).html
//         : Reference : Web site : EventingBasicConsumer https://www.rabbitmq.com/releases/rabbitmq-dotnet-client/v1.4.0/rabbitmq-dotnet-client-1.4.0-net-2.0-htmldoc/type-RabbitMQ.Client.Events.EventingBasicConsumer.html
//         : Reference : Web site : BasicConsume https://www.rabbitmq.com/releases/rabbitmq-dotnet-client/v1.4.0/rabbitmq-dotnet-client-1.4.0-net-2.0-htmldoc/type-RabbitMQ.Client.IModel.html#method-M:RabbitMQ.Client.IModel.BasicConsume(System.UInt16,System.String,System.Boolean,System.Collections.IDictionary,RabbitMQ.Client.IBasicConsumer)
//         : Reference : Web site : C#でconstな配列を実現する (もっとクールにプログラミング) http://pgnote.net/?p=885
//         : Reference : Web site : AMQP-CPP (docsforge.com) http://docsforge.com/11/AMQP-CPP/docs/latest/namespace-AMQP/class-TcpConnection/
//
// Program : this
//         : Compile   : Command  : g++ -std=c++11 tamesi35a2_cpp.cpp -o tamesi35a2_cpp.exe -lev -lamqpcpp -pthread
//         : Execute   : Command  : // バックグラウンドで実行
//                                : ./tamesi35a2_cpp.exe --enqueue 1113 durable --dequeue 1112 durable autodelete > ./tamesi35a2_cpp.out.log 2> ./tamesi35a2_cpp.err.log < /dev/null &
//         : Stop      : Typing   : [Ctrl]+[C]
//--------------------------------------------------------------------------------
//
// メッセージの末尾に daze を付けます。
// デキューは「1112」、エンキューは「1113」キューに向けて行います。
// 標準入出力は、キーボード、画面には接続しないようにします。

#include <string> // std::string
#include <iostream> // std::cout
#include <sstream> // std::ostringstream
#include <chrono>
#include <thread> // sleep_for
#include <future> // thread

// プロセス間通信用
#include <ev.h>
#include <amqpcpp.h>
#include <amqpcpp/libev.h>

// このプログラム内だけで使われる数字。AMQP-CPPでの実装とは異なる。
// AMQP-CPPでの実装 : AMQP::durable=[1] AMQP::autodelete=[2] AMQP::passive=[8] AMQP::exclusive=[512]
enum LifeSpanType
{
    // RabbitMQが止まってもキューを残す
    durable = 1,
    // コンシューマーが1人も接続していなかったら消す
    autodelete = 0x1 << 1,
    // キューが存在するかどうかチェックするだけ。中身見ない時これ
    passive = 0x1 << 2,
    // この接続でだけ使える。この接続が切れたら消す
    exclusive = 0x1 << 3
};

static AMQP::Address ADDRESS{ "amqp://localhost:5672" };
// 0 : enqueue用設定
// 1 : dequeue用設定
static const int ENQUEUE_INDEX = 0;
static const int DEQUEUE_INDEX = 1;
static const int NUM_INDEX = 2;
static std::string name_queues[] = { "", "" };
static LifeSpanType lifeSpan_queues[] = { (LifeSpanType)0, (LifeSpanType)0 };
static LifeSpanType LifeSpanString_To_Enum(std::string lifeSpan)
{
    if ("durable"==lifeSpan) {
        return durable;
    } else if ("autodelete" == lifeSpan) {
        return autodelete;
    } else if ("passive" == lifeSpan) {
        return passive;
    } else if ("exclusive" == lifeSpan) {
        return exclusive;
    } else {
        std::cerr << "未対応のlifeSpan [" << lifeSpan << "]";
        exit(1);
    }
}
static int LifeSpanString_To_AmqpInt(LifeSpanType lifeSpan)
{
    if (durable == lifeSpan) {
        return AMQP::durable;
    }
    else if (autodelete == lifeSpan) {
        return AMQP::autodelete;
    }
    else if (passive == lifeSpan) {
        return AMQP::passive;
    }
    else if (exclusive == lifeSpan) {
        return AMQP::exclusive;
    }
    else {
        std::cerr << "未対応のlifeSpan [" << lifeSpan << "]";
        exit(1);
    }
}

static std::string Dump()
{
    static std::ostringstream sb;
    sb << "tamesi35a2_cs.cs Dump" << std::endl
        << "    name_queues         [ENQUEUE_INDEX]    =[" << name_queues[ENQUEUE_INDEX] << "]" << std::endl
        << "    lifeSpan_queues     [ENQUEUE_INDEX]    =[" << lifeSpan_queues[ENQUEUE_INDEX] << "]" << std::endl
        << "    ----" << std::endl
        << "    name_queues         [DEQUEUE_INDEX]    =[" << name_queues[DEQUEUE_INDEX] << "]" << std::endl
        << "    lifeSpan_queues     [DEQUEUE_INDEX]    =[" << lifeSpan_queues[DEQUEUE_INDEX] << "]" << std::endl
        << "    ----" << std::endl;
    return sb.str();
}

// 接続はシングルトンにします
//auto* loop = EV_DEFAULT;
//struct ev_loop** loop_queues = { EV_DEFAULT, EV_DEFAULT };


/// <summary>
/// 回転式バッファー。
/// これはメイン・スレッドに置く。
/// デキューのスレッドでエンキューすることはできない。
/// デキュー処理は、回転式バッファーを仲介にしてエンキュー処理にメッセージを渡す。
/// </summary>
namespace rotationBuffer
{
    const int bufferSize = 100;
    static std::string buffer[bufferSize] = {};
    static int bufferCursors[2] = { 0, 0 };
    const int PUT_INDEX = 0;
    const int GET_INDEX = 1;

    std::mutex _mutex;
    static void putMessage(std::string message)
    {
        std::unique_lock<std::mutex> lock(_mutex);
        buffer[bufferCursors[PUT_INDEX]] = message;
        bufferCursors[PUT_INDEX]++;
        if (!(bufferCursors[PUT_INDEX] < bufferSize))
        {
            bufferCursors[PUT_INDEX] = 0;
        }
    }
    static std::string getMessage()
    {
        std::unique_lock<std::mutex> lock(_mutex);
        if ("" != buffer[bufferCursors[GET_INDEX]])
        {
            std::string message = buffer[bufferCursors[GET_INDEX]];
            buffer[bufferCursors[GET_INDEX]] = "";
            bufferCursors[GET_INDEX]++;
            if (!(bufferCursors[GET_INDEX] < bufferSize))
            {
                bufferCursors[GET_INDEX] = 0;
            }
            return message;
        }
        return "";
    }
}

// メッセージキューにエンキュー
static void enqueue(std::string message)
{
    std::cout << "(^▽^)エンキュー開始だぜ☆" << std::endl;

    // エンキュー用の接続
    //struct ev_loop* loop;
    struct ev_loop* loop = EV_DEFAULT;

    AMQP::LibEvHandler handler{ loop };
    //AMQP::LibEvHandler handler{ loop_queues[ENQUEUE_INDEX] };
    AMQP::TcpConnection connection{ &handler, ADDRESS };
    std::cout << "(^▽^)接続したぜ☆" << std::endl;
    AMQP::TcpChannel channel{ &connection };
    std::cout << "(^▽^)チャンネル開いたぜ☆" << std::endl;

    std::string exchange_name = "myexchange";
    std::string routing_key = "";

    int lifeSpan = LifeSpanString_To_AmqpInt(lifeSpan_queues[ENQUEUE_INDEX]);

    channel.declareQueue(name_queues[ENQUEUE_INDEX], lifeSpan)
        .onError([&lifeSpan](const char* errMsg) {
        std::cerr << "error declaring queue: " << errMsg << " lifeSpan=[" << lifeSpan << "]" << "\n";
    });
    std::cout << "(^▽^)デクレア・キューしたぜ☆" << std::endl;

    channel.bindQueue(exchange_name, name_queues[ENQUEUE_INDEX], routing_key)
        .onSuccess([&connection, &channel, &exchange_name, &routing_key, &message]() {

        if (!channel.publish(exchange_name, routing_key, message.c_str(), message.size())) {
            std::cerr << "failed to publish?\n";
        }

        // break in ev loop.
        connection.close();
    });
    std::cout << "(^▽^)バインド・キューしたぜ☆" << std::endl;

    // このループは、パブリッシュ後に抜ける
    ev_run(loop);
    //ev_run(loop_queues[ENQUEUE_INDEX]);
}

// 受信できたときに割り込んでくる処理
// startConsume() しておくこと。
static std::string dequeue() {
    std::string message;

    while ("" == message)
    {
        message = rotationBuffer::getMessage();
    }

    return message;
}

//// メッセージ・キューの送信を担当
//static void workProduce()
//{
//
//}

// メッセージ・キューの監視を開始
static void workConsume()
{
    std::cout << "(^q^)コンシューム開始だぜ☆" << std::endl;

    // Connect to the AMQP service.
    //struct ev_loop* loop;
    struct ev_loop* loop = EV_DEFAULT;

    AMQP::LibEvHandler handler{ loop };
    //AMQP::LibEvHandler handler(loop_queues[DEQUEUE_INDEX]);
    AMQP::TcpConnection connection(&handler, ADDRESS);
    std::cout << "(^q^)接続したぜ☆" << std::endl;
    AMQP::TcpChannel channel(&connection);
    std::cout << "(^q^)チャンネル開いたぜ☆" << std::endl;

    // I will go to the front of the box named "1111".
    int lifeSpan = LifeSpanString_To_AmqpInt(lifeSpan_queues[DEQUEUE_INDEX]);
    channel.declareQueue(name_queues[DEQUEUE_INDEX], lifeSpan);
    std::cout << "(^q^)デクレア・キューしたぜ☆" << std::endl;

    // I look inside the box.
    auto errorCb = [&lifeSpan](const char *errMsg) {
        std::cerr << "My ID watching failed [" << errMsg << "] lifeSpan=[" << lifeSpan << "]" << std::endl;
    };
    auto messageCb = [&channel](const AMQP::Message &message, uint64_t deliveryTag, bool redelivered) {

        std::string myString(message.body(), message.bodySize());
        rotationBuffer::putMessage(myString);

        channel.ack(deliveryTag);
    };
    channel.consume(name_queues[DEQUEUE_INDEX])
        .onReceived(messageCb)
        .onError(errorCb);
    std::cout << "(^q^)コンシュームしたぜ☆" << std::endl;

    // I will keep on forever.
    ev_run(loop);
    //ev_run(loop_queues[DEQUEUE_INDEX], 0);

    // I will not come here.
    return;
}

int main(int argc, char* argv[])
{
    std::cout << "(^q^)Welcome! AMQP::durable=[" << AMQP::durable << "] AMQP::autodelete=[" << AMQP::autodelete << "] AMQP::passive=[" << AMQP::passive << "] AMQP::exclusive=[" << AMQP::exclusive << "]" << std::endl;

    // 引数の解析
    if(0<argc)
    {
        // プログラム名を省き、コマンドライン引数だけをつなげる。
        std::string cmdArg;
        for (int i = 1; i < argc; ++i)
        {
            cmdArg += std::string(argv[i]);
            if (i < argc) {
                cmdArg += " ";
            }
        }
        std::cout << "(^q^)cmdArg=[" << cmdArg << "]" << std::endl;
        std::istringstream data(cmdArg);
        //data >> std::skipws;
        std::cout << "(^q^)data.str()=[" << data.str() << "]" << std::endl;

        // 与件
        // 「--enqueue 1117 durable autodelete --dequeue 1116 durable autodelete」
        // 寿命は可変個数設定可能「durable」「autodelete」「passive」「exclusive」

        // 受け皿
        std::string queueNames[2] = {}; // 結果はこれらの配列に入れる
        std::vector<std::string> lifespans[2] = {};

        // 記憶
        int m0 = -1; // 0:enqueue, 1:dequeue
        int m1 = -1; // lifespans index.

        // 解析器
        std::string a;
        while (data >> a) {
            std::cout << "(^_^)a0=[" << a << "]" << std::endl;

            if ("--enqueue" == a)
            {
                std::cout << "(^q^)エンキュー!" << std::endl;
                m0 = 0;
                m1 = -1;
            }
            else if ("--dequeue" == a)
            {
                std::cout << "(^q^)デキュー!" << std::endl;
                m0 = 1;
                m1 = -1;
            }
            else if (-1 == m1 && 0 == m0) {
                std::cout << "(^q^)エンキューのキュー名!" << std::endl;
                queueNames[m0] = a; // キュー名
                lifespans[m0] = std::vector<std::string>();// 配列の中にリストを準備
                m1++;
            }
            else if (-1 == m1 && 1 == m0) {
                std::cout << "(^q^)デキューのキュー名!" << std::endl;
                queueNames[m0] = a; // キュー名
                lifespans[m0] = std::vector<std::string>();// 配列の中にリストを準備
                m1++;
            }
            else
            {
                std::cout << "(^q^)寿命! m0=[" << m0 << "] m1=[" << m1 << "]" << std::endl;
                lifespans[m0].push_back(a);
                std::cout << "(^q^)zyumyo-!" << std::endl;
            } // 要素数-1 で最後の要素
        }
        std::cout << "(^-^)Loop end." << std::endl;

        if ("" == queueNames[0] || "" == queueNames[1]) {
            std::cerr << "コマンドライン引数の「--enqueue キュー名 寿命」「--dequeue キュー名 寿命」を漏れなく指定してください。例: --enqueue 1117 durable autodelete --dequeue 1116 durable autodelete" << std::endl;
            std::cerr << "queueNames[0]=[" << queueNames[0] << "]" << std::endl;
            //std::cerr << "queueNames[1]=[" << queueNames[1] << "]" << std::endl;
            //std::cerr << Dump();
            exit(1);
        }
        std::cout << "(^q^)エンキューのキュー名=[" << queueNames[0] << "]" << std::endl;
        std::cout << "(^q^)デキューのキュー名=[" << queueNames[1] << "]" << std::endl;
        std::cout << "(^q^)エンキューの寿命の数=[" << lifespans[0].size() << "]" << std::endl;
        std::cout << "(^q^)デキューの寿命の数=[" << lifespans[1].size() << "]" << std::endl;

        // エンキュー
        {
            m0 = 0;
            name_queues[ENQUEUE_INDEX] = queueNames[m0];
            lifeSpan_queues[ENQUEUE_INDEX] = (LifeSpanType)0;
            {
                for (std::string lifespan : lifespans[m0])
                {
                    lifeSpan_queues[ENQUEUE_INDEX] = (LifeSpanType)((int)lifeSpan_queues[ENQUEUE_INDEX] | (int)LifeSpanString_To_Enum(lifespan));
                }
            }
        }
        std::cout << "(^q^)エンキューおわり name_queues[ENQUEUE_INDEX]=[" << name_queues[ENQUEUE_INDEX] << "] lifeSpan_queues[ENQUEUE_INDEX]=[" << lifeSpan_queues[ENQUEUE_INDEX] << "]" << std::endl;

        // デキュー
        {
            m0 = 1;
            name_queues[DEQUEUE_INDEX] = queueNames[m0];
            lifeSpan_queues[DEQUEUE_INDEX] = (LifeSpanType)0;
            {
                for (std::string lifespan : lifespans[m0])
                {
                    lifeSpan_queues[DEQUEUE_INDEX] = (LifeSpanType)((int)lifeSpan_queues[DEQUEUE_INDEX] | (int)LifeSpanString_To_Enum(lifespan));
                }
            }
        }
        std::cout << "(^q^)デキューおわり name_queues[DEQUEUE_INDEX]=[" << name_queues[DEQUEUE_INDEX] << "] lifeSpan_queues[DEQUEUE_INDEX]=[" << lifeSpan_queues[DEQUEUE_INDEX] << "]" << std::endl;

        std::cout << Dump();
        std::cout << "(^q^)ダンプおわり" << std::endl;
    }
    else
    {
        std::cerr << "コマンドライン引数を指定してください。例: --enqueue 1117 durable autodelete --dequeue 1116 durable autodelete";
        exit(1);
    }

    // デキューの常時監視をスタート
    auto th1 = std::thread([] { workConsume(); });

    // 無限ループ
    std::cout << "(^q^)メッセージ監視ループに入るぜ☆" << std::endl;
    for (;;)
    {
        std::string message = rotationBuffer::getMessage();
        if ("" != message)
        {
            std::cout << "(^q^)メッセージを受け取ったか?" << std::endl;

            // 末尾に daze を付ける。
            message += "daze";

            // エンキューする
            enqueue( message);
        }
        std::this_thread::sleep_for(std::chrono::milliseconds(20));
    }

    // このプログラムは、自分では接続を切らない。

    // th1 スレッドの終了を待つ
    th1.join();

    std::cout << "(^q^)Finished!" << std::endl;
    return 0;
}

これでメモリ・リークはしてないぜ。

# ./tamesi35a2_cpp.exe --enqueue 1113 durable --dequeue 1112 durable autodelete > ./tamesi35a2_cpp.out.log 2> ./tamesi35a2_cpp.err.log < /dev/null &
[1] 18787

標準入力も捨てておくぜ。

# cd ..
[1]+  Exit 1                  ./tamesi35a2_cpp.exe --enqueue 1113 durable --dequeue 1112 durable autodelete > ./tamesi35a2_cpp.out.log 2> ./tamesi35a2_cpp.err.log < /dev/null  (wd: /home/★user/shogi/cpp_service)
(wd now: /home/★user/shogi)

おや、終了している?

tamesi35a2_cpp.out.log

(^q^)Welcome! AMQP::durable=[1] AMQP::autodelete=[2] AMQP::passive=[8] AMQP::exclusive=[512]
(^q^)cmdArg=[--enqueue 1113 durable --dequeue 1112 durable autodelete ]
(^q^)data.str()=[--enqueue 1113 durable --dequeue 1112 durable autodelete ]
(^_^)a0=[--enqueue]
(^q^)エンキュー!
(^_^)a0=[1113]
(^q^)エンキューのキュー名!
(^_^)a0=[durable]
(^q^)寿命! m0=[0] m1=[0]
(^q^)zyumyo-!
(^_^)a0=[--dequeue]
(^q^)デキュー!
(^_^)a0=[1112]
(^q^)デキューのキュー名!
(^_^)a0=[durable]
(^q^)寿命! m0=[1] m1=[0]
(^q^)zyumyo-!
(^_^)a0=[autodelete]
(^q^)寿命! m0=[1] m1=[0]
(^q^)zyumyo-!
(^-^)Loop end.
(^q^)エンキューのキュー名=[1113]
(^q^)デキューのキュー名=[1112]
(^q^)エンキューの寿命の数=[1]
(^q^)デキューの寿命の数=[2]
(^q^)エンキューおわり name_queues[ENQUEUE_INDEX]=[1113] lifeSpan_queues[ENQUEUE_INDEX]=[1]
(^q^)デキューおわり name_queues[DEQUEUE_INDEX]=[1112] lifeSpan_queues[DEQUEUE_INDEX]=[3]
tamesi35a2_cs.cs Dump
    name_queues         [ENQUEUE_INDEX]    =[1113]
    lifeSpan_queues     [ENQUEUE_INDEX]    =[1]
    ----
    name_queues         [DEQUEUE_INDEX]    =[1112]
    lifeSpan_queues     [DEQUEUE_INDEX]    =[3]
    ----
(^q^)ダンプおわり
(^q^)メッセージ監視ループに入るぜ☆
(^q^)コンシューム開始だぜ☆
(^q^)接続したぜ☆
(^q^)チャンネル開いたぜ☆
# nano tamesi35a2_cpp.err.log
未対応のlifeSpan [3]

1 と 2 を足して 3 なんだが コード書いてなかったか。

static int LifeSpanString_To_AmqpInt(LifeSpanType lifeSpan)
{
    int amqpInt = 0;
    if ( ((int)durable & (int)lifeSpan) == (int)durable) {
        amqpInt |= AMQP::durable;
    }

    if (((int)autodelete & (int)lifeSpan) == (int)autodelete) {
        amqpInt |= AMQP::autodelete;
    }

    if (((int)passive & (int)lifeSpan) == (int)passive) {
        amqpInt |= AMQP::passive;
    }

    if (((int)exclusive & (int)lifeSpan) == (int)exclusive) {
        amqpInt |= AMQP::exclusive;
    }

    return amqpInt;
}

これでどうか?

# jobs
[1]+  Running                 ./tamesi35a2_cpp.exe --enqueue 1113 durable --dequeue 1112 durable autodelete > ./tamesi35a2_cpp.out.log 2> ./tamesi35a2_cpp.err.log < /dev/null &
# ./tamesi34_cs.exe
削除したいキューがあれば名前を、無ければ空文字列を入れろだぜ☆(^~^)
キュー名を入力    : キューを削除します
空文字列で[Enter] : 次のステップへ進む
Name or empty ? >
エンキュー先のメッセージ・キューの名前を入れろだぜ☆(^~^)
Queue name? > 1112
エンキュー先のメッセージ・キューの寿命を、足し算して答えろだぜ☆(^~^)
(1) durable    : RabbitMQが止まってもキューを残す
(2) autodelete : コンシューマーが1人も接続していなかったら消す
(4) passive    : キューが存在するかどうかチェックするだけ。中身見ない時これ
(8) exclusive  : この接続でだけ使える。この接続が切れたら消す
Number ? > 1
デキュー先のメッセージ・キューの名前を入れろだぜ☆(^~^)
Queue name? > 1113
デキュー先のメッセージ・キューの寿命を、足し算して答えろだぜ☆(^~^)
(1) durable    : RabbitMQが止まってもキューを残す
(2) autodelete : コンシューマーが1人も接続していなかったら消す
(4) passive    : キューが存在するかどうかチェックするだけ。中身見ない時これ
(8) exclusive  : この接続でだけ使える。この接続が切れたら消す
Number ? > 3
tamesi34_cs.cs Dump
    name_queues         [ENQUEUE_INDEX]    =[1112]
    lifeSpan_queues     [ENQUEUE_INDEX]    =[Durable]
    durable_lifeSpans   [ENQUEUE_INDEX]    =[True]
    autodelete_lifeSpans[ENQUEUE_INDEX]    =[False]
    passive_lifeSpans   [ENQUEUE_INDEX]    =[False]
    exclusive_lifeSpans [ENQUEUE_INDEX]    =[False]
    ----
    name_queues         [DEQUEUE_INDEX]    =[1113]
    lifeSpan_queues     [DEQUEUE_INDEX]    =[Durable, Autodelete]
    durable_lifeSpans   [DEQUEUE_INDEX]    =[True]
    autodelete_lifeSpans[DEQUEUE_INDEX]    =[True]
    passive_lifeSpans   [DEQUEUE_INDEX]    =[False]
    exclusive_lifeSpans [DEQUEUE_INDEX]    =[False]
    ----
    name_queues         [DELETEQUEUE_INDEX]=[]
    lifeSpan_queues     [DELETEQUEUE_INDEX]=[0]
    durable_lifeSpans   [DELETEQUEUE_INDEX]=[False]
    autodelete_lifeSpans[DELETEQUEUE_INDEX]=[False]
    passive_lifeSpans   [DELETEQUEUE_INDEX]=[False]
    exclusive_lifeSpans [DELETEQUEUE_INDEX]=[False]
    ----

(tamesi34_cs.cs?) GetChannel index = [1]
    name_queues[index] = [1113]
    passive_lifeSpans[index] = [False]
    durable_lifeSpans[index] = [True]
    exclusive_lifeSpans[index] = [False]
    autodelete_lifeSpans[index] = [True]
    nowait は仮に false 固定
    arguments は仮に null 固定
終了するときは[Ctrl]+[C]キーを押せだぜ☆(^~^)
エンキューするときはメッセージを打ち込んで[Enter]キーを押せだぜ☆(^◇^)
Enqueue? > usi
tamesi34_cs.cs Dump
    name_queues         [ENQUEUE_INDEX]    =[1112]
    lifeSpan_queues     [ENQUEUE_INDEX]    =[Durable]
    durable_lifeSpans   [ENQUEUE_INDEX]    =[True]
    autodelete_lifeSpans[ENQUEUE_INDEX]    =[False]
    passive_lifeSpans   [ENQUEUE_INDEX]    =[False]
    exclusive_lifeSpans [ENQUEUE_INDEX]    =[False]
    ----
    name_queues         [DEQUEUE_INDEX]    =[1113]
    lifeSpan_queues     [DEQUEUE_INDEX]    =[Durable, Autodelete]
    durable_lifeSpans   [DEQUEUE_INDEX]    =[True]
    autodelete_lifeSpans[DEQUEUE_INDEX]    =[True]
    passive_lifeSpans   [DEQUEUE_INDEX]    =[False]
    exclusive_lifeSpans [DEQUEUE_INDEX]    =[False]
    ----
    name_queues         [DELETEQUEUE_INDEX]=[]
    lifeSpan_queues     [DELETEQUEUE_INDEX]=[0]
    durable_lifeSpans   [DELETEQUEUE_INDEX]=[False]
    autodelete_lifeSpans[DELETEQUEUE_INDEX]=[False]
    passive_lifeSpans   [DELETEQUEUE_INDEX]=[False]
    exclusive_lifeSpans [DELETEQUEUE_INDEX]=[False]
    ----

(tamesi34_cs.cs?) GetChannel index = [0]
    name_queues[index] = [1112]
    passive_lifeSpans[index] = [False]
    durable_lifeSpans[index] = [True]
    exclusive_lifeSpans[index] = [False]
    autodelete_lifeSpans[index] = [False]
    nowait は仮に false 固定
    arguments は仮に null 固定

Unhandled Exception:
RabbitMQ.Client.Exceptions.OperationInterruptedException: The AMQP operation was interrupted: AMQP close-reason, initiated by Peer, code=406, text="PRECONDITION_FAILED - inequivalent arg 'auto_delete' for queue '1112' in vhost '/': received 'false' but current is 'true'", classId=50, methodId=10, cause=
  at RabbitMQ.Client.Impl.SimpleBlockingRpcContinuation.GetReply () <0x40459fe0 + 0x00103> in <filename unknown>:0
  at RabbitMQ.Client.Impl.ModelBase.ModelRpc (RabbitMQ.Client.Impl.MethodBase method, RabbitMQ.Client.Impl.ContentHeaderBase header, System.Byte[] body) <0x40457da0 + 0x000f9> in <filename unknown>:0
  at RabbitMQ.Client.Framing.Impl.v0_8.Model.QueueDeclare (System.String queue, Boolean passive, Boolean durable, Boolean exclusive, Boolean autoDelete, Boolean nowait, IDictionary arguments) <0x4045cf00 + 0x00113> in <filename unknown>:0
  at UsagiMQ.Program.GetChannel (Int32 index) <0x4041d8c0 + 0x0045c> in <filename unknown>:0
  at UsagiMQ.Program.Enqueue (System.String message) <0x4045dfe0 + 0x00013> in <filename unknown>:0
  at UsagiMQ.Program.Main (System.String[] args) <0x40418d50 + 0x009a7> in <filename unknown>:0
[ERROR] FATAL UNHANDLED EXCEPTION: RabbitMQ.Client.Exceptions.OperationInterruptedException: The AMQP operation was interrupted: AMQP close-reason, initiated by Peer, code=406, text="PRECONDITION_FAILED - inequivalent arg 'auto_delete' for queue '1112' in vhost '/': received 'false' but current is 'true'", classId=50, methodId=10, cause=
  at RabbitMQ.Client.Impl.SimpleBlockingRpcContinuation.GetReply () <0x40459fe0 + 0x00103> in <filename unknown>:0
  at RabbitMQ.Client.Impl.ModelBase.ModelRpc (RabbitMQ.Client.Impl.MethodBase method, RabbitMQ.Client.Impl.ContentHeaderBase header, System.Byte[] body) <0x40457da0 + 0x000f9> in <filename unknown>:0
  at RabbitMQ.Client.Framing.Impl.v0_8.Model.QueueDeclare (System.String queue, Boolean passive, Boolean durable, Boolean exclusive, Boolean autoDelete, Boolean nowait, IDictionary arguments) <0x4045cf00 + 0x00113> in <filename unknown>:0
  at UsagiMQ.Program.GetChannel (Int32 index) <0x4041d8c0 + 0x0045c> in <filename unknown>:0
  at UsagiMQ.Program.Enqueue (System.String message) <0x4045dfe0 + 0x00013> in <filename unknown>:0
  at UsagiMQ.Program.Main (System.String[] args) <0x40418d50 + 0x009a7> in <filename unknown>:0

さて、何だったか。

tamesi34_cs.cs

// OS  : Windows 10
// IDE : Visual Studio 2015
//       Install : NuGet   : Install-Package RabbitMQ.Client -Version 4.1.1
//
// OS  : Ubuntu 16.04
//       Compile : Command : mcs /r:RabbitMQ.Client.dll -define:UBUNTU tamesi34_cs.cs
//       Execute : Command : // フォアグラウンドで実行する
//                         : ./tamesi34_cs.exe 2> ./tamesi34_cs.err.log
//       Check   : Command : // キューの中身の数を調べる
//                         : rabbitmqctl list_queues
//
// Library : RabbitMQ
//           Refference : Website : RabbitMQ http://www.rabbitmq.com/
//                      : Website : RabbitMQ管理コマンド(rabbitmqctl)使い方 (Qiita) http://qiita.com/tamikura@github/items/5293cda4c0026b2d7022
//                      : Website : amqpを使ってRabbitMQのキューを操作する (Qiita) http://qiita.com/tamikura@github/items/a268afa51c5537ca4fe6
//--------------------------------------------------------------------------------
// tamesi34_cs.cs

// Ubuntu の RabbitMQ はソースのバージョンが古いのか、API が異なった。
// #define UBUNTU

using RabbitMQ.Client;
using RabbitMQ.Client.Events;
using System;
using System.Text;

namespace UsagiMQ
{
    /// <summary>
    /// このプログラム内だけで使われる数字。AMQP-CPPでの実装とは異なる。
    /// AMQP-CPPでの実装 : AMQP::durable=[1] AMQP::autodelete=[2] AMQP::passive=[8] AMQP::exclusive=[512]
    /// </summary>
    [Flags]
    enum LifeSpanType
    {
        /// <summary>
        /// RabbitMQが止まってもキューを残す
        /// </summary>
        Durable = 1,
        /// <summary>
        /// コンシューマーが1人も接続していなかったら消す
        /// </summary>
        Autodelete = 0x1<<1,
        /// <summary>
        /// キューが存在するかどうかチェックするだけ。中身見ない時これ
        /// </summary>
        Passive = 0x1 << 2,
        /// <summary>
        /// この接続でだけ使える。この接続が切れたら消す
        /// </summary>
        Exclusive = 0x1 << 3
    }

    /// <summary>
    /// メッセージを エンキューします。
    /// キューの名前は指定してください。
    /// デキューは割込みを受け付けます。
    /// 
    /// 参照 : QueueDeclare (v1.0) http://docs.spring.io/spring-amqp-net/docs/1.0.x/api/html/Spring.Messaging.Amqp.Rabbit~Spring.Messaging.Amqp.Rabbit.Connection.CachedModel~QueueDeclare(String,Boolean,Boolean,Boolean,Boolean,Boolean,IDictionary).html
    /// 参照 : EventingBasicConsumer https://www.rabbitmq.com/releases/rabbitmq-dotnet-client/v1.4.0/rabbitmq-dotnet-client-1.4.0-net-2.0-htmldoc/type-RabbitMQ.Client.Events.EventingBasicConsumer.html
    /// 参照 : QueueDelete (v1.4) https://www.rabbitmq.com/releases/rabbitmq-dotnet-client/v1.4.0/rabbitmq-dotnet-client-1.4.0-net-2.0-htmldoc/type-RabbitMQ.Client.IModel.html#method-M:RabbitMQ.Client.IModel.QueueDelete(System.UInt16,System.String,System.Boolean,System.Boolean,System.Boolean)
    /// 参照 : BasicConsume https://www.rabbitmq.com/releases/rabbitmq-dotnet-client/v1.4.0/rabbitmq-dotnet-client-1.4.0-net-2.0-htmldoc/type-RabbitMQ.Client.IModel.html#method-M:RabbitMQ.Client.IModel.BasicConsume(System.UInt16,System.String,System.Boolean,System.Collections.IDictionary,RabbitMQ.Client.IBasicConsumer)
    /// 参照 : C#でconstな配列を実現する (もっとクールにプログラミング) http://pgnote.net/?p=885
    /// </summary>
    class Program
    {
        static string Dump()
        {
            StringBuilder sb = new StringBuilder();
            sb.AppendLine("tamesi34_cs.cs Dump");
            sb.AppendLine("    name_queues         [ENQUEUE_INDEX]    =[" + name_queues[ENQUEUE_INDEX]+"]");
            sb.AppendLine("    lifeSpan_queues     [ENQUEUE_INDEX]    =[" + lifeSpan_queues[ENQUEUE_INDEX] + "]");
            sb.AppendLine("    durable_lifeSpans   [ENQUEUE_INDEX]    =[" + durable_lifeSpans[ENQUEUE_INDEX] + "]");
            sb.AppendLine("    autodelete_lifeSpans[ENQUEUE_INDEX]    =[" + autodelete_lifeSpans[ENQUEUE_INDEX] + "]");
            sb.AppendLine("    passive_lifeSpans   [ENQUEUE_INDEX]    =[" + passive_lifeSpans[ENQUEUE_INDEX] + "]");
            sb.AppendLine("    exclusive_lifeSpans [ENQUEUE_INDEX]    =[" + exclusive_lifeSpans[ENQUEUE_INDEX] + "]");
            sb.AppendLine("    ----");
            sb.AppendLine("    name_queues         [DEQUEUE_INDEX]    =[" + name_queues[DEQUEUE_INDEX] + "]");
            sb.AppendLine("    lifeSpan_queues     [DEQUEUE_INDEX]    =[" + lifeSpan_queues[DEQUEUE_INDEX] + "]");
            sb.AppendLine("    durable_lifeSpans   [DEQUEUE_INDEX]    =[" + durable_lifeSpans[DEQUEUE_INDEX] + "]");
            sb.AppendLine("    autodelete_lifeSpans[DEQUEUE_INDEX]    =[" + autodelete_lifeSpans[DEQUEUE_INDEX] + "]");
            sb.AppendLine("    passive_lifeSpans   [DEQUEUE_INDEX]    =[" + passive_lifeSpans[DEQUEUE_INDEX] + "]");
            sb.AppendLine("    exclusive_lifeSpans [DEQUEUE_INDEX]    =[" + exclusive_lifeSpans[DEQUEUE_INDEX] + "]");
            sb.AppendLine("    ----");
            sb.AppendLine("    name_queues         [DELETEQUEUE_INDEX]=[" + name_queues[DELETEQUEUE_INDEX] + "]");
            sb.AppendLine("    lifeSpan_queues     [DELETEQUEUE_INDEX]=[" + lifeSpan_queues[DELETEQUEUE_INDEX] + "]");
            sb.AppendLine("    durable_lifeSpans   [DELETEQUEUE_INDEX]=[" + durable_lifeSpans[DELETEQUEUE_INDEX] + "]");
            sb.AppendLine("    autodelete_lifeSpans[DELETEQUEUE_INDEX]=[" + autodelete_lifeSpans[DELETEQUEUE_INDEX] + "]");
            sb.AppendLine("    passive_lifeSpans   [DELETEQUEUE_INDEX]=[" + passive_lifeSpans[DELETEQUEUE_INDEX] + "]");
            sb.AppendLine("    exclusive_lifeSpans [DELETEQUEUE_INDEX]=[" + exclusive_lifeSpans[DELETEQUEUE_INDEX] + "]");
            sb.AppendLine("    ----");
            return sb.ToString();
        }

        const int ENQUEUE_INDEX = 0;
        const int DEQUEUE_INDEX = 1;
        const int DELETEQUEUE_INDEX = 2;
        const int NUM_INDEX = 3;
        const string HOST_NAME = "localhost";
        static string[] name_queues = new string[NUM_INDEX];
        /// <summary>
        /// キューの寿命(複合可能)
        /// durable    : RabbitMQが止まってもキューを残す
        /// autodelete : コンシューマーが1人も接続していなかったら消す
        /// passive    : キューが存在するかどうかチェックするだけ。中身見ない時これ
        /// exclusive  : この接続でだけ使える。この接続が切れたら消す
        /// </summary>
        static LifeSpanType[] lifeSpan_queues = new LifeSpanType[NUM_INDEX];
        static bool[]
            durable_lifeSpans = new bool[NUM_INDEX],
            autodelete_lifeSpans = new bool[NUM_INDEX],
            passive_lifeSpans = new bool[NUM_INDEX],
            exclusive_lifeSpans = new bool[NUM_INDEX];
        static void SetLifeSpan(int index_queue, string name_queue, LifeSpanType lifeSpan)
        {
            name_queues[index_queue] = name_queue;
            lifeSpan_queues[index_queue] = lifeSpan;

            // 一旦クリアー
            durable_lifeSpans[index_queue] = false;
            autodelete_lifeSpans[index_queue] = false;
            passive_lifeSpans[index_queue] = false;
            exclusive_lifeSpans[index_queue] = false;

            // durable
            if (((int)lifeSpan & (int)LifeSpanType.Durable) == (int)LifeSpanType.Durable) { durable_lifeSpans[index_queue] = true; }
            // autodelete
            if (((int)lifeSpan & (int)LifeSpanType.Autodelete) == (int)LifeSpanType.Autodelete) { autodelete_lifeSpans[index_queue] = true; }
            // passive
            if (((int)lifeSpan & (int)LifeSpanType.Passive) == (int)LifeSpanType.Passive) { passive_lifeSpans[index_queue] = true; }
            // exclusive
            if (((int)lifeSpan & (int)LifeSpanType.Exclusive) == (int)LifeSpanType.Exclusive) { exclusive_lifeSpans[index_queue] = true; }
        }


        public static ConnectionFactory GetFactory()
        {
            if (null == m_factory_)
            {
                m_factory_ = new ConnectionFactory() { HostName = HOST_NAME };
                Console.WriteLine("(^q^)ファクトリーを用意したぜ☆ HostName=[" + HOST_NAME + "]");
            }
            return m_factory_;
        }
        static ConnectionFactory m_factory_;

        public static IConnection GetConnection()
        {
            if (null == m_connection_)
            {
                m_connection_ = GetFactory().CreateConnection();
                Console.WriteLine("(^q^)接続したぜ☆");
            }
            return m_connection_;
        }
        static IConnection m_connection_;

        public static IModel GetChannel(int index)
        {
            if (null == m_channels_[index])
            {
                m_channels_[index] = GetConnection().CreateModel();

                // 引数が7つの QueueDeclare でエラーを吐くことがあるので、情報を出力しておく。
                Console.Error.WriteLine(Dump());
                Console.Error.WriteLine("(tamesi34_cs.cs?) GetChannel index = [" + index + "]");
                Console.Error.WriteLine("    name_queues[index] = [" + name_queues[index] + "]");
                Console.Error.WriteLine("    passive_lifeSpans[index] = [" + passive_lifeSpans[index] + "]");
                Console.Error.WriteLine("    durable_lifeSpans[index] = [" + durable_lifeSpans[index] + "]");
                Console.Error.WriteLine("    exclusive_lifeSpans[index] = [" + exclusive_lifeSpans[index] + "]");
                Console.Error.WriteLine("    autodelete_lifeSpans[index] = [" + autodelete_lifeSpans[index] + "]");
                Console.Error.WriteLine("    nowait は仮に false 固定");
                Console.Error.WriteLine("    arguments は仮に null 固定");

#if UBUNTU
                // Ubuntuでは何故か Spring.Messaging.Amqp.Rabbit の引数 7 つのやつになっている。
                // RabbitMQ.Client.Framing.Impl.v0_8.Model.QueueDeclare (System.String queue, Boolean passive, Boolean durable, Boolean exclusive, Boolean autoDelete, Boolean nowait, IDictionary arguments)
                // そして false になっているようだ。
                m_channels_[index].QueueDeclare(name_queues[index], passive_lifeSpans[index], durable_lifeSpans[index], exclusive_lifeSpans[index], autodelete_lifeSpans[index], false, null);
                //m_channels_[index].QueueDeclare(name_queues[index], false, false, false, false, false, null);
#else
                m_channels_[index].QueueDeclare(name_queues[index], durable_lifeSpans[index], exclusive_lifeSpans[index], autodelete_lifeSpans[index], null);
#endif
            }

            Console.WriteLine("(^q^)チャンネルを開いたぜ☆ message=[" + index + "]");
            return m_channels_[index];
        }
        static IModel[] m_channels_ = new IModel[NUM_INDEX];

        public static EventingBasicConsumer GetConsumer(int index)
        {
            if (null == m_consumers_[index])
            {
#if UBUNTU
                // Ubuntuでは何故か v1.4.0 の引数が 0 個のやつになっている。調べたが引数が1個~6個のものは無かった。
                m_consumers_[index] = new EventingBasicConsumer();
#else
                m_consumers_[index] = new EventingBasicConsumer(GetChannel(index));
#endif
            }
            Console.WriteLine("(^q^)コンシューマーを取得したぜ☆ index=["+ index + "]");
            return m_consumers_[index];
        }
        static EventingBasicConsumer[] m_consumers_ = new EventingBasicConsumer[NUM_INDEX];

        /// <summary>
        /// 受信できたときに割り込んでくる処理
        /// </summary>
#if UBUNTU
        public static BasicDeliverEventHandler GetDequeueHandler()
#else
        public static EventHandler<BasicDeliverEventArgs> GetDequeueHandler()
#endif
        {
            if (null == m_dequeueHandler_)
            {
#if UBUNTU
                m_dequeueHandler_ = new BasicDeliverEventHandler((model, ea) =>
#else
                m_dequeueHandler_ = new EventHandler<BasicDeliverEventArgs>((model, ea) =>
#endif
                {
                    byte[] body = ea.Body;
                    string message = Encoding.UTF8.GetString(body);
                    Console.WriteLine("<---- [interrupt!] Dequeue(^q^) {0}", message);
                });
            }

            return m_dequeueHandler_;
        }

#if UBUNTU
        static BasicDeliverEventHandler m_dequeueHandler_;
#else
        static EventHandler<BasicDeliverEventArgs> m_dequeueHandler_;
#endif

        /// <summary>
        /// 対応するオープンは無いけれど、開けたら閉める、を完璧に対応する必要がある。
        /// </summary>
        static void CloseConnection()
        {
            if (null != m_connection_)
            {
                m_connection_.Close();
                m_connection_ = null;
                Console.WriteLine("(^q^)接続を閉じたぜ☆");
            }
        }
        /// <summary>
        /// 対応するオープンは無いけれど、開けたら閉める、を完璧に対応する必要がある。
        /// </summary>
        static void CloseChannel(int index)
        {
            if (null != m_channels_[index])
            {
                m_channels_[index].Close();
                m_channels_[index] = null;
                Console.WriteLine("(^q^)チャンネルを閉じたぜ☆");
            }
        }

        static void Main(string[] args)
        {
            //----------------------------------------
            // Delete
            //----------------------------------------
            for (;;)
            {
                Console.Write(@"削除したいキューがあれば名前を、無ければ空文字列を入れろだぜ☆(^~^)
キュー名を入力    : キューを削除します
空文字列で[Enter] : 次のステップへ進む
Name or empty ? > ");
                string queueName_delete = Console.ReadLine();
                if (""== queueName_delete.Trim())
                {
                    break;
                }


                Console.Write(@"削除するメッセージ・キューの寿命を、足し算して答えろだぜ☆(^~^)
("+ ((int)LifeSpanType.Durable) + @") durable    : RabbitMQが止まってもキューを残す
(" + ((int)LifeSpanType.Autodelete) + @") autodelete : コンシューマーが1人も接続していなかったら消す
(" + ((int)LifeSpanType.Passive) + @") passive    : キューが存在するかどうかチェックするだけ。中身見ない時これ
(" + ((int)LifeSpanType.Exclusive) + @") exclusive  : この接続でだけ使える。この接続が切れたら消す
Number ? > ");
                LifeSpanType lifeSpan_delete = (LifeSpanType)int.Parse(Console.ReadLine());
                SetLifeSpan(DELETEQUEUE_INDEX, queueName_delete, lifeSpan_delete);
                uint result = DeleteQueue();
                Console.WriteLine(@"["+ queueName_delete + "]キューを削除したはずだぜ☆(^~^) result=["+ result + "]");
            }

            //----------------------------------------
            // Enqueue settings
            //----------------------------------------
            for (;;)
            {
                Console.Write(@"エンキュー先のメッセージ・キューの名前を入れろだぜ☆(^~^)
Queue name? > ");
                string queueName_enqueue = Console.ReadLine();

                Console.Write(@"エンキュー先のメッセージ・キューの寿命を、足し算して答えろだぜ☆(^~^)
(" + ((int)LifeSpanType.Durable) + @") durable    : RabbitMQが止まってもキューを残す
(" + ((int)LifeSpanType.Autodelete) + @") autodelete : コンシューマーが1人も接続していなかったら消す
(" + ((int)LifeSpanType.Passive) + @") passive    : キューが存在するかどうかチェックするだけ。中身見ない時これ
(" + ((int)LifeSpanType.Exclusive) + @") exclusive  : この接続でだけ使える。この接続が切れたら消す
Number ? > ");
                int lifeSpan_enqueue;
                if(int.TryParse(Console.ReadLine(),out lifeSpan_enqueue))
                {
                    SetLifeSpan(ENQUEUE_INDEX, queueName_enqueue, (LifeSpanType)lifeSpan_enqueue);
                    break;
                }
            }

            //----------------------------------------
            // Enqueue settings
            //----------------------------------------
            for (;;)
            {
                Console.Write(@"デキュー先のメッセージ・キューの名前を入れろだぜ☆(^~^)
Queue name? > ");
                string queueName_dequeue = Console.ReadLine();

                Console.Write(@"デキュー先のメッセージ・キューの寿命を、足し算して答えろだぜ☆(^~^)
(" + ((int)LifeSpanType.Durable) + @") durable    : RabbitMQが止まってもキューを残す
(" + ((int)LifeSpanType.Autodelete) + @") autodelete : コンシューマーが1人も接続していなかったら消す
(" + ((int)LifeSpanType.Passive) + @") passive    : キューが存在するかどうかチェックするだけ。中身見ない時これ
(" + ((int)LifeSpanType.Exclusive) + @") exclusive  : この接続でだけ使える。この接続が切れたら消す
Number ? > ");
                int lifeSpan_dequeue;
                if(int.TryParse(Console.ReadLine(),out lifeSpan_dequeue))
                {
                    SetLifeSpan(DEQUEUE_INDEX, queueName_dequeue, (LifeSpanType)lifeSpan_dequeue);

                    StartConsume();
                    break;
                }
            }

            Console.Write(@"終了するときは[Ctrl]+[C]キーを押せだぜ☆(^~^)
エンキューするときはメッセージを打ち込んで[Enter]キーを押せだぜ☆(^◇^)
Enqueue? > ");
            for (;;)
            {
                // "Hello World!" などを入力
                string line = Console.ReadLine();
                Enqueue(line);
                Console.Write(@"Enqueue? > ");
            }

            // ここには来ない
            // CloseConnection();
        }

        static uint DeleteQueue()
        {
            IModel channel = GetChannel(DELETEQUEUE_INDEX);

#if UBUNTU
            // Ubuntuでは何故か 昔の .Net 用の引数 5 つのやつの変則版になっている。
            // uint QueueDelete(ushort ticket, string queue, bool ifUnused, bool ifEmpty, bool nowait)
            uint result = channel.QueueDelete( name_queues[DELETEQUEUE_INDEX],true,true,true);
#else
            uint result = channel.QueueDelete(name_queues[DELETEQUEUE_INDEX],true,true);
#endif

            // 対応するオープンは無いが、ちゃんと閉じないと、レシーブしてくれない。
            CloseChannel(DELETEQUEUE_INDEX);
            return result;
        }

        static void Enqueue(string message)
        {
            Console.WriteLine("(^q^)Enqueue: エンキュー開始☆ message=[" + message + "]");

            IModel channel = GetChannel(ENQUEUE_INDEX);

            byte[] body = Encoding.UTF8.GetBytes(message);
            Console.WriteLine("(^q^)Enqueue: body.Length=[" + body.Length+"]");

            channel.BasicPublish("", name_queues[ENQUEUE_INDEX], null, body);
            Console.WriteLine("(^q^)Enqueue: パブリッシュしたぜ。キュー名=[" + name_queues[ENQUEUE_INDEX] + "]");

            // 対応するオープンは無いが、ちゃんと閉じないと、レシーブしてくれない。
            CloseChannel(ENQUEUE_INDEX);
        }

        static void StartConsume()
        {
            IModel channel = GetChannel(DEQUEUE_INDEX);
            EventingBasicConsumer consumer = GetConsumer(DEQUEUE_INDEX);

            // 受信できたときに割り込んでくる処理
            consumer.Received += GetDequeueHandler();

#if UBUNTU
            // Ubuntuでは何故か引数が 5 個のやつになっている。
            channel.BasicConsume( name_queues[DEQUEUE_INDEX], true, "", null, consumer);
#else
            channel.BasicConsume( name_queues[DEQUEUE_INDEX], true, consumer);
#endif
            // 終了はさせない
            // consumer.Received -= GetReceiveHandler();
            // CloseChannel(DEQUEUE_INDEX);
        }
    }
}
root@tk2-217-18401:/home/★user/shogi/csharp_service# mcs /r:RabbitMQ.Client.dll -define:UBUNTU tamesi34_cs.cs
root@tk2-217-18401:/home/★user/shogi/csharp_service# ./tamesi34_cs.exe 2> ./tamesi34_cs.err.log
削除したいキューがあれば名前を、無ければ空文字列を入れろだぜ☆(^~^)
キュー名を入力    : キューを削除します
空文字列で[Enter] : 次のステップへ進む
Name or empty ? >
エンキュー先のメッセージ・キューの名前を入れろだぜ☆(^~^)
Queue name? > 1112
エンキュー先のメッセージ・キューの寿命を、足し算して答えろだぜ☆(^~^)
(1) durable    : RabbitMQが止まってもキューを残す
(2) autodelete : コンシューマーが1人も接続していなかったら消す
(4) passive    : キューが存在するかどうかチェックするだけ。中身見ない時これ
(8) exclusive  : この接続でだけ使える。この接続が切れたら消す
Number ? > 1
デキュー先のメッセージ・キューの名前を入れろだぜ☆(^~^)
Queue name? > 1113
デキュー先のメッセージ・キューの寿命を、足し算して答えろだぜ☆(^~^)
(1) durable    : RabbitMQが止まってもキューを残す
(2) autodelete : コンシューマーが1人も接続していなかったら消す
(4) passive    : キューが存在するかどうかチェックするだけ。中身見ない時これ
(8) exclusive  : この接続でだけ使える。この接続が切れたら消す
Number ? > 2
(^q^)ファクトリーを用意したぜ☆ HostName=[localhost]
(^q^)接続したぜ☆
tamesi34_cs.cs Dump
    name_queues         [ENQUEUE_INDEX]    =[1112]
    lifeSpan_queues     [ENQUEUE_INDEX]    =[Durable]
    durable_lifeSpans   [ENQUEUE_INDEX]    =[True]
    autodelete_lifeSpans[ENQUEUE_INDEX]    =[False]
    passive_lifeSpans   [ENQUEUE_INDEX]    =[False]
    exclusive_lifeSpans [ENQUEUE_INDEX]    =[False]
    ----
    name_queues         [DEQUEUE_INDEX]    =[1113]
    lifeSpan_queues     [DEQUEUE_INDEX]    =[Autodelete]
    durable_lifeSpans   [DEQUEUE_INDEX]    =[False]
    autodelete_lifeSpans[DEQUEUE_INDEX]    =[True]
    passive_lifeSpans   [DEQUEUE_INDEX]    =[False]
    exclusive_lifeSpans [DEQUEUE_INDEX]    =[False]
    ----
    name_queues         [DELETEQUEUE_INDEX]=[]
    lifeSpan_queues     [DELETEQUEUE_INDEX]=[0]
    durable_lifeSpans   [DELETEQUEUE_INDEX]=[False]
    autodelete_lifeSpans[DELETEQUEUE_INDEX]=[False]
    passive_lifeSpans   [DELETEQUEUE_INDEX]=[False]
    exclusive_lifeSpans [DELETEQUEUE_INDEX]=[False]
    ----

(tamesi34_cs.cs?) GetChannel index = [1]
    name_queues[index] = [1113]
    passive_lifeSpans[index] = [False]
    durable_lifeSpans[index] = [False]
    exclusive_lifeSpans[index] = [False]
    autodelete_lifeSpans[index] = [True]
    nowait は仮に false 固定
    arguments は仮に null 固定
(^q^)チャンネルを開いたぜ☆ message=[1]
(^q^)コンシューマーを取得したぜ☆ index=[1]
終了するときは[Ctrl]+[C]キーを押せだぜ☆(^~^)
エンキューするときはメッセージを打ち込んで[Enter]キーを押せだぜ☆(^◇^)
Enqueue? > usi
(^q^)Enqueue: エンキュー開始☆ message=[usi]
tamesi34_cs.cs Dump
    name_queues         [ENQUEUE_INDEX]    =[1112]
    lifeSpan_queues     [ENQUEUE_INDEX]    =[Durable]
    durable_lifeSpans   [ENQUEUE_INDEX]    =[True]
    autodelete_lifeSpans[ENQUEUE_INDEX]    =[False]
    passive_lifeSpans   [ENQUEUE_INDEX]    =[False]
    exclusive_lifeSpans [ENQUEUE_INDEX]    =[False]
    ----
    name_queues         [DEQUEUE_INDEX]    =[1113]
    lifeSpan_queues     [DEQUEUE_INDEX]    =[Autodelete]
    durable_lifeSpans   [DEQUEUE_INDEX]    =[False]
    autodelete_lifeSpans[DEQUEUE_INDEX]    =[True]
    passive_lifeSpans   [DEQUEUE_INDEX]    =[False]
    exclusive_lifeSpans [DEQUEUE_INDEX]    =[False]
    ----
    name_queues         [DELETEQUEUE_INDEX]=[]
    lifeSpan_queues     [DELETEQUEUE_INDEX]=[0]
    durable_lifeSpans   [DELETEQUEUE_INDEX]=[False]
    autodelete_lifeSpans[DELETEQUEUE_INDEX]=[False]
    passive_lifeSpans   [DELETEQUEUE_INDEX]=[False]
    exclusive_lifeSpans [DELETEQUEUE_INDEX]=[False]
    ----

(tamesi34_cs.cs?) GetChannel index = [0]
    name_queues[index] = [1112]
    passive_lifeSpans[index] = [False]
    durable_lifeSpans[index] = [True]
    exclusive_lifeSpans[index] = [False]
    autodelete_lifeSpans[index] = [False]
    nowait は仮に false 固定
    arguments は仮に null 固定

反応がない。

tamesi34_cs.err.log

Unhandled Exception:
RabbitMQ.Client.Exceptions.OperationInterruptedException: The AMQP operation was interrupted: AMQP close-reason, initiated by Peer, code=406, text="PRECONDITION_FAILED - inequivalent arg 'auto_delete' for queue '1112' in vhost '/':$
  at RabbitMQ.Client.Impl.SimpleBlockingRpcContinuation.GetReply () <0x41a40570 + 0x00107> in <filename unknown>:0
  at RabbitMQ.Client.Impl.ModelBase.ModelRpc (RabbitMQ.Client.Impl.MethodBase method, RabbitMQ.Client.Impl.ContentHeaderBase header, System.Byte[] body) <0x41a3e3f0 + 0x000fd> in <filename unknown>:0
  at RabbitMQ.Client.Framing.Impl.v0_8.Model.QueueDeclare (System.String queue, Boolean passive, Boolean durable, Boolean exclusive, Boolean autoDelete, Boolean nowait, IDictionary arguments) <0x41a43420 + 0x00113> in <filename unk$
  at UsagiMQ.Program.GetChannel (Int32 index) <0x41a03d10 + 0x0045c> in <filename unknown>:0
  at UsagiMQ.Program.Enqueue (System.String message) <0x41a44550 + 0x00047> in <filename unknown>:0
  at UsagiMQ.Program.Main (System.String[] args) <0x419fed50 + 0x009a7> in <filename unknown>:0
[ERROR] FATAL UNHANDLED EXCEPTION: RabbitMQ.Client.Exceptions.OperationInterruptedException: The AMQP operation was interrupted: AMQP close-reason, initiated by Peer, code=406, text="PRECONDITION_FAILED - inequivalent arg 'auto_del$
  at RabbitMQ.Client.Impl.SimpleBlockingRpcContinuation.GetReply () <0x41a40570 + 0x00107> in <filename unknown>:0
  at RabbitMQ.Client.Impl.ModelBase.ModelRpc (RabbitMQ.Client.Impl.MethodBase method, RabbitMQ.Client.Impl.ContentHeaderBase header, System.Byte[] body) <0x41a3e3f0 + 0x000fd> in <filename unknown>:0
  at RabbitMQ.Client.Framing.Impl.v0_8.Model.QueueDeclare (System.String queue, Boolean passive, Boolean durable, Boolean exclusive, Boolean autoDelete, Boolean nowait, IDictionary arguments) <0x41a43420 + 0x00113> in <filename unk$
  at UsagiMQ.Program.GetChannel (Int32 index) <0x41a03d10 + 0x0045c> in <filename unknown>:0
  at UsagiMQ.Program.Enqueue (System.String message) <0x41a44550 + 0x00047> in <filename unknown>:0
  at UsagiMQ.Program.Main (System.String[] args) <0x419fed50 + 0x009a7> in <filename unknown>:0
# jobs
[1]+  Running                 ./tamesi35a2_cpp.exe --enqueue 1113 durable --dequeue 1112 durable autodelete > ./tamesi35a2_cpp.out.log 2> ./tamesi35a2_cpp.err.log < /dev/null &  (wd: /home/★user/shogi/cpp_service)

寿命が違うのか?

root@tk2-217-18401:/home/★user/shogi/csharp_service# jobs
[1]+  Running                 ./tamesi35a2_cpp.exe --enqueue 1113 durable --dequeue 1112 durable autodelete > ./tamesi35a2_cpp.out.log 2> ./tamesi35a2_cpp.err.log < /dev/null &  (wd: /home/★user/shogi/cpp_service)
root@tk2-217-18401:/home/★user/shogi/csharp_service# ./tamesi34_cs.exe 2> ./tamesi34_cs.err.log
削除したいキューがあれば名前を、無ければ空文字列を入れろだぜ☆(^~^)
キュー名を入力    : キューを削除します
空文字列で[Enter] : 次のステップへ進む
Name or empty ? >
エンキュー先のメッセージ・キューの名前を入れろだぜ☆(^~^)
Queue name? > 1112
エンキュー先のメッセージ・キューの寿命を、足し算して答えろだぜ☆(^~^)
(1) durable    : RabbitMQが止まってもキューを残す
(2) autodelete : コンシューマーが1人も接続していなかったら消す
(4) passive    : キューが存在するかどうかチェックするだけ。中身見ない時これ
(8) exclusive  : この接続でだけ使える。この接続が切れたら消す
Number ? > 3
デキュー先のメッセージ・キューの名前を入れろだぜ☆(^~^)
Queue name? > 1113
デキュー先のメッセージ・キューの寿命を、足し算して答えろだぜ☆(^~^)
(1) durable    : RabbitMQが止まってもキューを残す
(2) autodelete : コンシューマーが1人も接続していなかったら消す
(4) passive    : キューが存在するかどうかチェックするだけ。中身見ない時これ
(8) exclusive  : この接続でだけ使える。この接続が切れたら消す
Number ? > 1
(^q^)ファクトリーを用意したぜ☆ HostName=[localhost]
(^q^)接続したぜ☆
tamesi34_cs.cs Dump
    name_queues         [ENQUEUE_INDEX]    =[1112]
    lifeSpan_queues     [ENQUEUE_INDEX]    =[Durable, Autodelete]
    durable_lifeSpans   [ENQUEUE_INDEX]    =[True]
    autodelete_lifeSpans[ENQUEUE_INDEX]    =[True]
    passive_lifeSpans   [ENQUEUE_INDEX]    =[False]
    exclusive_lifeSpans [ENQUEUE_INDEX]    =[False]
    ----
    name_queues         [DEQUEUE_INDEX]    =[1113]
    lifeSpan_queues     [DEQUEUE_INDEX]    =[Durable]
    durable_lifeSpans   [DEQUEUE_INDEX]    =[True]
    autodelete_lifeSpans[DEQUEUE_INDEX]    =[False]
    passive_lifeSpans   [DEQUEUE_INDEX]    =[False]
    exclusive_lifeSpans [DEQUEUE_INDEX]    =[False]
    ----
    name_queues         [DELETEQUEUE_INDEX]=[]
    lifeSpan_queues     [DELETEQUEUE_INDEX]=[0]
    durable_lifeSpans   [DELETEQUEUE_INDEX]=[False]
    autodelete_lifeSpans[DELETEQUEUE_INDEX]=[False]
    passive_lifeSpans   [DELETEQUEUE_INDEX]=[False]
    exclusive_lifeSpans [DELETEQUEUE_INDEX]=[False]
    ----

(tamesi34_cs.cs?) GetChannel index = [1]
    name_queues[index] = [1113]
    passive_lifeSpans[index] = [False]
    durable_lifeSpans[index] = [True]
    exclusive_lifeSpans[index] = [False]
    autodelete_lifeSpans[index] = [False]
    nowait は仮に false 固定
    arguments は仮に null 固定
(^q^)チャンネルを開いたぜ☆ message=[1]
(^q^)コンシューマーを取得したぜ☆ index=[1]
終了するときは[Ctrl]+[C]キーを押せだぜ☆(^~^)
エンキューするときはメッセージを打ち込んで[Enter]キーを押せだぜ☆(^◇^)
Enqueue? > usi
(^q^)Enqueue: エンキュー開始☆ message=[usi]
tamesi34_cs.cs Dump
    name_queues         [ENQUEUE_INDEX]    =[1112]
    lifeSpan_queues     [ENQUEUE_INDEX]    =[Durable, Autodelete]
    durable_lifeSpans   [ENQUEUE_INDEX]    =[True]
    autodelete_lifeSpans[ENQUEUE_INDEX]    =[True]
    passive_lifeSpans   [ENQUEUE_INDEX]    =[False]
    exclusive_lifeSpans [ENQUEUE_INDEX]    =[False]
    ----
    name_queues         [DEQUEUE_INDEX]    =[1113]
    lifeSpan_queues     [DEQUEUE_INDEX]    =[Durable]
    durable_lifeSpans   [DEQUEUE_INDEX]    =[True]
    autodelete_lifeSpans[DEQUEUE_INDEX]    =[False]
    passive_lifeSpans   [DEQUEUE_INDEX]    =[False]
    exclusive_lifeSpans [DEQUEUE_INDEX]    =[False]
    ----
    name_queues         [DELETEQUEUE_INDEX]=[]
    lifeSpan_queues     [DELETEQUEUE_INDEX]=[0]
    durable_lifeSpans   [DELETEQUEUE_INDEX]=[False]
    autodelete_lifeSpans[DELETEQUEUE_INDEX]=[False]
    passive_lifeSpans   [DELETEQUEUE_INDEX]=[False]
    exclusive_lifeSpans [DELETEQUEUE_INDEX]=[False]
    ----

(tamesi34_cs.cs?) GetChannel index = [0]
    name_queues[index] = [1112]
    passive_lifeSpans[index] = [False]
    durable_lifeSpans[index] = [True]
    exclusive_lifeSpans[index] = [False]
    autodelete_lifeSpans[index] = [True]
    nowait は仮に false 固定
    arguments は仮に null 固定
(^q^)チャンネルを開いたぜ☆ message=[0]
(^q^)Enqueue: body.Length=[3]
(^q^)Enqueue: パブリッシュしたぜ。キュー名=[1112]
(^q^)チャンネルを閉じたぜ☆
Enqueue? >

パブリッシュはできたが。

[1]+  Aborted                 ./tamesi35a2_cpp.exe --enqueue 1113 durable --dequeue 1112 durable autodelete > ./tamesi35a2_cpp.out.log 2> ./tamesi35a2_cpp.err.log < /dev/null  (wd: /home/★user/shogi/cpp_service)
(wd now: /home/★user/shogi/csharp_service)

tamesi35a2_cpp.err.log

tamesi35a2_cpp.exe: ev.c:3541: ev_run: Assertion `("libev: ev_loop recursion during release detected", ((loop)->loop_done) != 0x80)' failed.

記事が長くなったので次へ

1
2
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
2