2

POSIX スレッドを使用して C で並列アルゴリズムをプログラムする方法を学ぼうとしています。私の環境は、gcc 4 を搭載した Mac OS X 10.5.5 です。

コンパイル:

gcc -Wall -D_REENTRANT -lpthread source.c -o test.o

したがって、私の問題は、これをUbuntu 9.04ボックスでコンパイルすると、スレッド順にスムーズに実行され、Macではミューテックスが機能しないように見え、スレッドは共有情報を取得するのを待ちません。

マック:

#1
#0
#2
#5
#3
#4

Ubuntu

#0
#1
#2
#3
#4
#5

何か案は?

ソースコードの下に従ってください:

#include <ctype.h>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <pthread.h>

#define NUM_THREADS 6
pthread_mutex_t mutexsum;
pthread_t threads[NUM_THREADS];
long Sum;

void *SumThreads(void *threadid){
    int tmp;
    int i,x[10],y[10];

    // Para cada x e y do vetor, jogamos o valor de i, só para meio didáticos
    for (i=0; i<10 ; i++){
        x[i] = i;
        y[i] = i;
    }


    tmp = Sum;
     for (i=0; i<10 ; i++){
         tmp += (x[i] * y[i]);
     }

       pthread_mutex_lock (&mutexsum);
       Sum += tmp;
       printf("Im thread #%ld sum until now is: %ld\n",threadid,Sum);
       pthread_mutex_unlock (&mutexsum);
       return 0;
}


int main(int argc, char *argv[]){
    int i;
    Sum = 0;

    pthread_mutex_init(&mutexsum, NULL);

    for(i=0; i<NUM_THREADS; i++){
        pthread_create(&threads[i], NULL, SumThreads, (void *)i);
    }

    pthread_exit(NULL);
}
4

3 に答える 3

10

スレッドを任意の順序で実行するコードには何もありません。Ubuntuで何らかの順序で実行されている場合、それはあなたが幸運であることが原因である可能性があります。Ubuntuで1000回実行してみて、同じ結果が何度も得られるかどうかを確認してください。

重要なのは、スケジューラーがスレッドにプロセッサーにアクセスさせる方法を制御できないということです。したがって、forループを繰り返してスレッドを作成する場合、 pthread_createの最初の呼び出しが最初に実行される、または最初に作成するミューテックスをロックすることを想定することはできません。それはOSレベルでのスケジューラー次第であり、独自のカーネルを作成しない限り、それを制御することはできません:-)。

シリアル動作が必要な場合、そもそもなぜコードを別々のスレッドで実行するのでしょうか。実験のためだけの場合は、pthread_signalを使用して特定のスレッドをウェイクアップして実行することを考えることができます...次に、ウェイクアップされたスレッドは2番目のスレッドをウェイクアップできます。

それが役に立てば幸い。

于 2009-09-11T12:52:39.443 に答える
0

私はCまたは他の言語でpthreadを実行しません(ただし、高性能コンピューターでスレッドプログラミングを実行します)ので、この「答え」は役に立たないかもしれません。

  • コードの中で、スレッドがミューテックスをスレッドIDの順序で渡す必要があるのは何ですか?スレッドはID順に作成されているようですが、その順序で実行する必要があるのは/

  • スレッドをID順に実行する必要がある場合、なぜですか?スレッドを作成してからシリアル化するように見えます。何のために?

  • スレッドでプログラムして実行順序を気にするときは、非常に多くのスレッドを作成して、実行順序がどうなるかを確認することがよくあります。

私が言うように、Cとpthreadの理解が不十分な場合は、これを無視してください。

于 2009-09-11T12:51:22.003 に答える
0

私の記憶では、保護した変数は実際にはプロセス間で共有されていません。各スレッド内の独自のコンテキストに存在します。したがって、何を印刷するかを決定するのは、各スレッドがいつスケジュールされるかだけです。

正確性が 0、1、2、3 の出力として定義されている場合、1 つの単純なミューテックスで正確性を保証できるとは思いません。

コードが行っていることは、sum 関数のコードを実行コードとして使用して、複数の実行コンテキストを作成することです。保護している変数は、静的として宣言されていない限り、その関数の呼び出しごとに一意になります。

最終的に、適切な順番になるまでスレッドをブロックする論理的な方法がないため、1 つのシステムが正しく出力されるのは偶然です。

于 2009-09-11T12:50:32.270 に答える