0

私は現在、処理するネットワークパケットをキューに入れる必要があるプロジェクトに取り組んでいます。利用可能なときにこれらのパケットを処理する最大25のスレッドを持つThreadPoolがあります。ただし、パケットデータ(クラスにカプセル化されている)をThreadPoolに関連付けられたthread_procメソッドに渡すと、データが破損します。ThreadPool変数を次のように宣言します。

pool = new ThreadPool<Packet>((Func<Packet>)thread_proc, 25, false);

これは、使用可能なパケットをチェックするスレッドメソッドです。

void* run()
{
    while (true)
    {
        var packet = packets.poll();

        try
        {
            pool.push(packet);
        }
        catch (ThreadError e)
        {
            error(e.message);
        }
    }

    return null;
}

「パケット」は、次のクラスのBlockingQueue(ミューテックスを使用したカスタムブロッキングキュー)です。

class Packet : Object
{
    public unowned ClientHandler client;
    public uint8[] data;
    public int index;
    public int size;

    public Packet(ClientHandler client, uint8[] data, int index, int size)
    {
        this.client = client;
        this.data = data;
        this.index = index;
        this.size = size;
    }
}

上記のクラスは、実際のパケットデータ(「データ」変数)を含むものです。Packetインスタンスがthread_procに到達するまでに、変数値はすべて間違っています...

なぜこれが起こっているのか、そして可能な解決策についての助けをいただければ幸いです。前もって感謝します。

〜マイケルK。

4

1 に答える 1

1

valac gitにコミットをプッシュしたところ、Valaがデータを自動的に管理できるようになりました。下位互換性が失われるため、新しいコンストラクター(ThreadPool.with_owned_data)とメソッド(プッシュの代わりに追加)を使用する必要があります。

valac gitへの依存を避けたい場合は、packet.ref ()プッシュする前にpacket.unref ()、コールバックの最後に(thread_proc)を実行できます。https://bugzilla.gnome.org/attachment.cgi?id=214884に例があります。

ThreadPoolコンストラクターでthread_procをキャストすると、新しいメモリ管理機能が壊れる可能性があることに注意してください。率直に言って、あなたは本当にデリゲートをキャストすることを避けるべきです...それはトラブルに巻き込まれるための素晴らしい方法です。thread_proc正しい署名を持つように関数(この場合)を修正する方がはるかに優れています。

于 2012-06-06T17:21:43.523 に答える