0

修正が必要なCプログラムの予期しない動作を誰かが解決するのを手伝ってくれることを願っています:

2 つの CAN バスのいずれかから着信メッセージを受信するまで待機する 2 つの Xenomai リアルタイム タスク (スレッド) があります。
各タスクは関数 checkMessageNumber() を呼び出しますが、予測できない結果が得られます。

優先順位に基づくシングル スレッド システムを使用していることに注意してください。1 つのスレッドが他のスレッドよりも優先されますが、一方のスレッドが他のスレッドよりも優先されると、一方のスレッドが途中で実行される可能性があります。
将来、ハードウェアがマルチスレッド システムにアップグレードされる可能性はありますが、プログラムのこの部分は依然として単一のスレッド (1 つの CPU コア) に限定されます。

各スレッドがこの関数の独自のインスタンスを呼び出すことを理解しているため、何が起こっているのかわかりません。

int getMessageIndex(unsigned int msg_number)
{
    unsigned int i = 0;
    while(i < global_number_message_boxes)
    { 
        if (global_message_box[i].id == msg_number}
            return i; // matched the msg number, so return the index number
        i++;
    }
    return -1; // no match found
}

もともと、この関数は非常に予測不可能であり、メッセージがストリーミングされて 2 つのタスクによって処理されると (メッセージの送信元のハードウェア バスによって異なります)、着信 'msg_number' が 'id と一致した場合でも、この関数は -1 を返すことがありました。 'global_message_box' 構造体で。

「global_number_message_boxes」を整数に設定することで、よりうまく機能させることができました
while(i < 50)
ただし、一致するはずなのに、関数が -1 を返すことがあります。

グローバル変数しか読み取っていないのに、なぜ破損するのですか? これについて何を学ぶ必要がありますか?

私の考えは、着信 'msg_number' が単純に 'global_message_box' の 'id' になるように単純化することです。
各スレッドは、どの「id」を書き込むかをチェックすることなく、構造体に直接書き込みます。
ミューテックスを使用することはどれほど重要ですか? システム設計により、各スレッドが構造体の同じ部分に書き込むことは決してないので、それが重要かどうかはわかりませんか?

ありがとう。

4

2 に答える 2

3

これは、グローバル構造体の周りのスレッド同期の欠如に帰着する可能性があります。この関数は読み取りだけだと言います。global_number_message_boxesわかりましたが、別のスレッドがorを書き込む別の関数を呼び出したらどうなるglobal_message_boxでしょうか? グローバルとそれらにアクセスする複数のスレッドがあるシステムでは、セーフルールは次のとおりです。すべてのアクセスをロックします。使用しているプラ​​ットフォームが読み取り/書き込みロックをサポートしている可能性もあるため、書き込みを行っていない限り、複数のスレッドが同時に読み取ることができます。

于 2012-10-18T08:22:14.573 に答える
1

ロックとセマフォはここであなたの友達になります。2つのスレッドを使用してデータを書き込むと、さまざまな問題が発生します。

スレッドが関数に入るときは、他のスレッドをブロックし、終了時にそれらのスレッドのブロックを解除する必要があります。これにより、スレッドセーフな操作が保証され、一貫した結果が得られます。

于 2012-10-18T08:24:10.753 に答える