0

タイマーの割り当てと割り当て解除のための 2 つの関数があります。

Allocate timer はタイマーを割り当て、割り当てられたタイマーに int を返します。

int allocate_timer(void)
{
  int count = 0;
  int allocated = 0;
    /*Loop to find the first timer that is not allocated*/
    for(count = 0; count< ARRAY_SIZE; count++)
    {
            if(allocated_timers[count] == '0')
            {
                    /*When the next timer available timer is found it is set to allocated and timer is set to zero*/
                    allocated_timers[count] = '1';
                    timers[count] = 0;
                    break;
            }

            else if(allocated > ARRAY_SIZE - 1)
            {
                printf("No timers available\n");
                exit(0);

            }

            else
            {
                allocated++;
            }

    }
    /*Position of the allocated timer is returned*/
    return count;
}

タイマーの割り当て解除、割り当て解除される位置への int を受け取ります

void deallocate_one_timer(int position)
{       
    if(TIMER_ALLOCATED == allocated_timers[position])
    {
            allocated_timers[position] = '0';
            timers[position] = 0;
    }
}

すでにある以上に堅牢にすることはできません。それらをより良くする方法について何かアドバイスはありますか?

4

2 に答える 2

3

変数allocatedは常に等しいcount(したがって削除される可能性があります)ため、IMOを使用する'0'と、配列'1'の値として混乱する可能性があります。allocated_timers通常はと0です1

どちらもそのままではコードの堅牢性に影響を与えませんが、コードが理解しやすいほど、将来の変更に対してより堅牢になります。

timers各タイマーにエントリがあり、対応するエントリがある場合のように、2つの「並列」配列がある場合、2つのメンバーallocated_timersを持つaの単一の配列struct(この場合はおそらく)を使用する方がよいかどうかを検討する価値があります。名前付きvalueおよびallocated)。良くない場合もありますが、読者がこれら2つの配列が密接に関連していることを発見して覚えておく必要がないため、コードの理解に役立つことがよくあります。

deallocate_one_timer配列インデックスとして使用する前positionに範囲内にあることを確認した場合、呼び出し元による誤った使用に対してわずかに堅牢にすることができます。関数がこれらのチェックを行う責任があると言っているわけではありませんが、他の場所でバグを診断するのに役立つ場合があります。このような必須ではないチェックに使用できます。2つの利点があります。まず、チェックはこの関数が処理する責任ではなく、他の誰かが本来あるべきことをしたことをチェックしているだけであることを自己文書化します。次に、プログラムを小さくしたり速くしたりする必要がある場合は、プログラムの非デバッグビルドですべてのアサーションを簡単に無効にできます。0ARRAY_SIZEassertassert

同様に、現在割り当てられていないタイマーの割り当てが解除された場合は、潜在的な問題を示している可能性があるため、エラーメッセージを表示して終了すると役立つ場合があります。割り当てを2回解除する人は、他の誰かが割り当てを解除する可能性があります。つまり、他の誰かが突然、タイマーを排他的に使用できなくなったことに気付きます。

最後に、timers[index]割り当てと割り当て解除の両方で0に設定します。新しく割り当てられたタイマーが正しい初期値を持つことを保証するために実際にどの関数が責任を負うかという問題を混乱させることを除いて、それは特に悪いことではありません。割り当て解除関数は何も実行しないか、割り当てられたタイマーが保持できない値にタイマーを設定する可能性があります(タイマーが0から上がると仮定すると、おそらく-1)。これにより、デバッグ時に、値が-1のタイマーを使用すると、問題が発生しました。

最後に、このコードは(明らかに)スレッドセーフではありません。これは一種の非堅牢性であると私は思います。マルチスレッドプログラムで使用できないコードを書くことは恥ずべきことではありません。特に、スレッドを作成する能力さえない組み込みシステムではそうです。それが意図的な決定であり、文書化されている限り。

于 2012-08-15T17:43:10.560 に答える
1
  • 「0」と「1」を使用するか、または deallocate_one_timer で使用される TIMER_ALLOCATED などの定数を使用するかを決定し、一貫性を保ちます。

  • allocated変数の使用は冗長です。ループは次のように優れています。

    int allocate_timer(void)
    {
        int count;
    
        for (count = 0; count < ARRAY_SIZE; count++)
        {
            if (allocated_timers[count] == '0')
            {
                allocated_timers[count] = '1';
                timers[count] = 0;
                return count;
            }
        }
        fprintf(stderr, "No timers available\n");
        exit(EXIT_FAILURE);
    }
    

または、失敗しても終了せず、戻ってエラーになる方がよいかもしれません。

于 2012-08-15T18:20:37.790 に答える