2011-12-14 15 views
1


私は教授の講義ノートでレビューをしています。私は同時セッションセクションに達したときにこの質問を得ました:
スライドで、教授はpthreadを使用する2つの例を挙げました(1つは良い例、もう1つは悪い例です)。しかし、なぜ彼らの間に違いがあるのか​​分かりません。悪いものは最初のものとは異なり、そしてなぜ、なぜ私に説明してくださいpthreadとのCプログラムの同時実行

#include <stdio.h> 
#include <stdlib.h> 
#include <pthread.h> 
void *get_rand_num(void *args) { 
    int *nump = malloc(sizeof(int)); 
    srand(pthread_self()); 
    *nump = rand(); 
    return nump; 
} 
int main() { 
    pthread_t tid; 
    void *ptr = NULL; 
    pthread_create(&tid, NULL, get_rand_num, NULL); 
    pthread_join(tid, &ptr); 
    printf("Random number: %d\n", * (int *) ptr); 
    return 0; 
} 

と悪い例が

#include <stdio.h> 
#include <stdlib.h> 
#include <pthread.h> 
void *get_rand_num(void *args) { 
    int num; 
    srand(pthread_self()); 
    num = rand(); 
    return &num; 
} 
int main() { 
    pthread_t tid; 
    void *ptr = NULL; 
    pthread_create(&tid, NULL, get_rand_num, NULL); 
    pthread_join(tid, &ptr); 
    printf("Random number: %d\n", * (int *) ptr); 
    return 0; 
} 

で誰もがこれらの2つの例を理解することができます:ここ
は良い例ですそれは良くない?


はあなた
アラン

答えて

5

悪い例は、ローカル変数へのポインタを返しありがとうございます。これは、関数が返ってきたときにローカル変数が消滅するため、常に悪い考えです。これはマルチスレッドプログラムに特有の問題ではありませんが、スレッドはスレッドごとに1つのスタックを取得し、pthread_joinの後に割り当てが解除されるため悪化します。シングルスレッドプログラミングでは幸運なことが多く、関数のリターン直後にポインタを使用することができますが、古いスレッドのスタックを含むセグメント全体が悪い例でオペレーティングシステムに戻ってしまい、アクセスによってセグメント化エラーが発生する可能性があります。

最初の例では、メモリリークが発生するため、あまり良くありません。

+0

ありがとう、私はそれを持っていると思います!ところで、最初の例では、割り当てられたメモリを解放するために行を追加することで改善すべきという意味ですか? 'free(nump)'のように?プログラムにこの行をどこに置くべきだと思いますか? 'pthread_join()'の前に置くべきですか? –

+0

技術的には、プログラムが短命でメモリがプログラム終了時にOSによって自動的に再利用されるため、メモリリークはなく、悪い習慣です。 – Ioan

+0

@AllanJiang:いいえ、絶対にありません。単純なルール、 'malloc'に従ってください。メモリを使い、終了したら' free'を実行してください。 'printf'呼び出しの後に置きます。 – thiton

1

戻り値& numここで、numはスタック上のローカル変数で、関数スコープでのみ有効です。あなたが戻ったら、もう有効ではありません。

0

悪いケースは、スタックから少し離れたところにポインタを戻します。これは、長い時間前にウィンドウから飛び出した鳥のようです!

しかし、それがうまくいくと、あなたは非常に非常に乱数を持っているでしょう - スレッドのIDで乱数生成器を呼び出すより少し良いです!

+0

実際には、別のプログラム(攻撃ベクトル)によってアクセス可能なメモリ内の場所を直接参照するため、ランダムではありません。 – Ioan

+0

喜んで人はここの周りにユーモアのビットがあります。いずれにせよ、私はそのことで良い推測をすることができた***ランダム***番号 –

+0

ユーモラスな確かに;興味深いことを指摘しています。 :-) – Ioan

関連する問題