2

私は、pthreads を使用しなければならないマルチスレッドのエラトステネスのふるいを書いています。これを行う方法は、mutex と cond_waits を使用することだと確信しています。プログラムの最初に 4 つのスレッドを作成し、エラトステネスのふるいが素数を見つけるまで待機させる必要があります。次に、スレッドのブロックを解除して、ビット配列内の素数のすべての反復をマークダウンできるようにする必要があります。次に、エラトステネスのふるいアルゴリズムが新しい数を使い果たすまで、再びブロックして次の素数を待つ必要があります。

これは私のスレッド化された関数のコードです:

while(!doneFlag){
        printf("Thread wile loop\n");
        pthread_mutex_lock(&lock);
        pthread_cond_wait(&cond, &lock);

        startingPosition = (double)(maxNum/numThreads) * i;
        endingPosition = (double)(maxNum/numThreads) * (i+1)-1;
        if(i == numThreads-1){
            endingPosition = maxNum;
        } 
... Until the end of the function ... 
pthread_mutex_unlock(&lock);
}
return (void*)0;

doneFlag は、エラトステネスのふるいアルゴリズムがすべての数値で終了したときに 1 に設定するフラグです。cond_wait() 関数を使用した while ループにより、スレッドが入力を待機するようになることを期待していました (入力が残っている限り)。

main() 関数の Sieve 部分は次のとおりです。

while(outerCounter < sqrt(maxNum)){
    //searching numbers above the current for prime numbers
    //printf("Sieve While\n");
    for(innerCounter = outerCounter+1; innerCounter <= maxNum; innerCounter++){
        //not composite
        //printf("Sieve for\n");
        if(composite[innerCounter] == 0){

            printf("Prime found: %d\n", innerCounter);
            pthread_mutex_lock(&lock);
            pthread_cond_broadcast(&cond);
            pthread_mutex_unlock(&lock);

            outerCounter = innerCounter;
            numPrimes++;

        }
    }
}
doneFlag = 1;

どういうわけか、合成数は合成としてマークされていません (カップルはいますが)。main() 関数との競合状態と関係があるため、スレッドがまだバックグラウンドで実行されている間に素数を見つけ続け、それによってスレッドがまだ動作している間に素数を変更する方法を推測します。

どうすればこれを修正できますか? locks/cond_wait は適切に設定されていますか? このオンラインのリソースを見つけるのに本当に苦労しています。

ありがとう!

編集: また、各スレッドが関数を同時に実行できるようにしたい (関数は、配列内の要素を複合としてマークするものです)。ミューテックスを一緒に実行したいので、スレッド関数ではミューテックスはお勧めできませんか? (各スレッドは配列の異なるセグメントを取ります)

4

1 に答える 1

1

ファイヤズクルが最初に言った。ミュートの代わりにカウンティング セマフォを使用します。プロデューサー/コンシューマーを調べてください。それがあなたが解決している問題です!

ですから、あなたが使用しているアルゴリズムには詳しくありませんが、理解しようと努めたので、もう少し助けてあげられると思います。新しいプライムはそれぞれ新しい仕事だと思いますか?

いずれにせよ、ジョブ スレッドがジョブ キューから新しいジョブを取得し、必要なすべての情報を取得できるように、自己完結型のジョブを生成するメイン ループが必要です。ジョブが単に新しい素数である場合は、新しい素数をキューに追加し、カウンティング セマフォを送信します (ただし、キューには同期が必要であることを思い出してください)。

スレッドは、最初にカウンティング セマフォで保留されます。セマフォがシグナル状態になると、スレッドが起動し、sem がシグナル状態になる前にキューに入れられたジョブをフェッチします。次に、スレッドがジョブを処理し、結果を送信します。

あなたの問題は、明示的なジョブパラメーターを使用して新しいジョブを生成する集中型の方法がないため、2 つ以上のスレッドがウェイクアップして同じジョブを取得するか、まったくないことだと思います。

于 2013-03-05T07:18:27.370 に答える