0

マルチスレッドプログラミングで悩んでいます...

CAN to USB モジュールを介して外部デバイスと通信するアプリケーションがあります。アプリケーションは CAN バス上で正常に通信していますが、アプリケーションが毎秒「ハートビート」メッセージを送信する必要があります。

これは、スレッドを使用するのに最適な時期のように思われるので、1 秒ごとに起動してハートビートを送信するスレッドを作成しました。私が抱えている問題は、CAN バス インターフェイスの共有です。ハートビートは、バスがアイドル状態のときにのみ送信する必要があります。リソースを共有するにはどうすればよいですか?

ここに私がこれまでに持っているものを示す擬似コードがあります:

TMainThread
{
    Init:
        CanBusApi =new TCanBusApi;
        MutexMain =CreateMutex( "CanBusApiMutexName" );

        HeartbeatThread =new THeartbeatThread( CanBusApi );

    Execution:
        WaitForSingleObject( MutexMain );
        CanBusApi->DoSomething();
        ReleaseMutex( MutexMain );
}

THeartbeatThread( CanBusApi )
{
    Init:
        MutexHeart =CreateMutex( "CanBusApiMutexName" );

    Execution:
        Sleep( 1000 );
        WaitForSingleObject( MutexHeart );
        CanBusApi->DoHeartBeat();
        ReleaseMutex( MutexHeart );
}

私が見ている問題は、DoHeartBeat が呼び出されると、予想どおり MutexMain を待っている間にメイン スレッドがブロックされることですが、DoHeartBeat も停止します。DoHeartBeat は、WaitForSingleObject(MutexMain) が失敗してタイムアウトになるまで完了しません。

DoHeartBeat は MainThread または HeartBeatThread のコンテキストで実行されますか? MainThread で実行しているようです。

私は何を間違っていますか?より良い方法はありますか?

ありがとう、デビッド

4

2 に答える 2

0

CAN バス API は内部でシングルスレッド化されていると思われます。DoHeartBeat() リクエストを 2 番目のスレッドからメイン スレッドにマーシャリングしている可能性があります。その場合、メイン スレッドがブロックされているため、成功する方法はありません。これは、基本的に 2 つの方法で修正できます。(1) 2 番目のスレッドではなく、ハートビートを実行するようにメイン スレッドにメッセージを送信します。または(2)2番目のスレッドの代わりに、メインスレッドでハートビートのタイマーを使用します。(私は、この特定の問題に対してマルチスレッドはやり過ぎだと思います。)

于 2010-03-23T15:10:52.990 に答える
0

まず、ハートビートに関する仕様を読み直してください。実際のハートビート メッセージを毎秒受信する必要がある、または毎秒何らかのメッセージを受信する必要があり、他のメッセージが送信されていない場合にハートビートを使用する必要があると書かれていますか? チャネル上のデータの存在は、通信チャネルが有効であることの事実上の証拠であるため、特定のハートビート メッセージは必要ありません。

実際のハートビート メッセージが必要であり、それが毎秒必要な場合、上記のコードではミューテックスが 1 つだけ存在し、両方のスレッドがそれを共有する必要があります。記述されたコードは 2 つの別個のミューテックスを作成するため、どちらも実際にはブロックされません。チャネルで衝突が発生し、CanBusApi で悪いことが起こります。MainMutex をグローバル/クラス変数として表示し、両方のスレッドで参照できるようにします。

于 2010-03-23T15:12:12.760 に答える