2

2 つのスレッドを使用する必要があります。1 つは行列に対してさまざまな操作を実行するためのもので、もう 1 つは行列操作プロセスのさまざまな時点で仮想メモリを監視するためのものです。このメソッドは、グローバル状態変数「フラグ」を使用するために必要です。

これまでのところ、次のものがあります(簡潔にするために一部を省略しています):

int flag = 0;

int allocate_matrices(int dimension)
{
    while (flag == 0) {} //busy wait while main prints memory state

    int *matrix = (int *) malloc(sizeof(int)*dimension*dimension);
    int *matrix2 = (int *) malloc(sizeof(int)*dimension*dimension);

    flag = 0;
    while (flag == 0) {} //busy wait while main prints memory state

    // more similar actions...
}

int memory_stats()
{
    while (flag == 0)
    { system("top"); flag = 1; }
}

int main()
{ //threads are created and joined for these two functions }

ご想像のとおり、system("top")呼び出しが 1 回行われ、行列が割り当てられた後、プログラムは無限ループに陥ります。memory_statsこれは、関数に割り当てられたスレッドがすでにその役割を果たしているためであるため、フラグが再び更新されることはないように思えます。

これを回避するエレガントな方法はありますか?メモリ統計を 4 回出力する必要があることはわかっているので、memory_stats関数内に 4 つの while ループを記述し、それぞれの間にグローバル フラグを条件としてビジー待機を行うことができると思いますが、それは私には扱いにくいように思えます。ヘルプやポインタをいただければ幸いです。

4

4 に答える 4

6

ミューテックスでロックできます。pthread を使用していると仮定します。

pthread_mutex_t mutex;

pthread_mutex_lock(&mutex);
flag=1;
pthread_mutex_unlock (&mutex);

これは、pthreads、mutex、およびその他のものに関する非常に優れたチュートリアルです: https://computing.llnl.gov/tutorials/pthreads/

于 2013-04-09T19:31:06.557 に答える
6

ハングの考えられる理由の 1 つは、これflagが通常の変数であり、コンパイラは、この内部のflag = 0;while (flag == 0) {}またはの間でゼロ以外の値に設定されていないことを確認することです。したがって、変数が0のままでループが無限になると「考え」ます。コンパイラは、スレッドを完全に無視します。whileallocate_matrices()

上記のことが起こらないようにflagasを定義することはできますが、 . 1つには、変数の変更のアトミック性は保証されません。volatilevolatilevolatile

別の問題は、コンパイラが副作用のない無限ループを検出した場合、未定義の動作となされ、何かが発生する可能性があることです。または、少なくとも、考えていることではなく、これも発生する可能性があります。

ミューテックスなどの適切な同期プリミティブを使用する必要があります。

于 2013-04-09T19:51:25.310 に答える
0

この問題は、最新の C 標準である C11 に準拠した C コンパイラで解決できます。C11にはスレッドと と呼ばれるデータ型atomic_flagがあり、質問にあるように基本的にスピンロックに使用できます。

于 2013-04-09T20:52:32.603 に答える
-1

まず、変数flagを宣言する必要があります。volatileそうしないと、コンパイラーは最初の変数の後に読み取りを省略するライセンスを持っています。

邪魔にならないように、シーケンサー/event_counter を使用できます。1 つのスレッドは変数が奇数の場合にインクリメントし、もう 1 つのスレッドは偶数の場合にインクリメントします。1 つのスレッドが常に変数を「所有」し、インクリメントとともに所有権を譲渡するため、競合状態は発生しません。

于 2013-04-09T19:43:00.923 に答える