私は、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 は適切に設定されていますか? このオンラインのリソースを見つけるのに本当に苦労しています。
ありがとう!
編集: また、各スレッドが関数を同時に実行できるようにしたい (関数は、配列内の要素を複合としてマークするものです)。ミューテックスを一緒に実行したいので、スレッド関数ではミューテックスはお勧めできませんか? (各スレッドは配列の異なるセグメントを取ります)