との奇妙な問題は、これが私のコードです:シンプル素数プログラム - スレッドC#
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading;
namespace FirePrime
{
class Program
{
static bool[] ThreadsFinished;
static bool[] nums;
static bool AllThreadsFinished()
{
bool allThreadsFinished = false;
foreach (var threadFinished in ThreadsFinished)
{
allThreadsFinished &= threadFinished;
}
return allThreadsFinished;
}
static bool isPrime(int n)
{
if (n < 2) { return false; }
if (n == 2) { return true; }
if (n % 2 == 0) { return false; }
int d = 3;
while (d * d <= n)
{
if (n % d == 0) { return false; }
d += 2;
}
return true;
}
static void MarkPrimes(int startNumber,int stopNumber,int ThreadNr)
{
for (int j = startNumber; j < stopNumber; j++)
nums[j] = isPrime(j);
lock (typeof(Program))
{
ThreadsFinished[ThreadNr] = true;
}
}
static void Main(string[] args)
{
int nrNums = 100;
int nrThreads = 10;
//var threadStartNums = new List<int>();
ThreadsFinished = new bool[nrThreads];
nums = new bool[nrNums];
//var nums = new List<bool>();
nums[0] = false;
nums[1] = false;
for(int i=2;i<nrNums;i++)
nums[i] = true;
int interval = (int)(nrNums/nrThreads);
//threadStartNums.Add(2);
//int aux = firstStartNum;
//int i = 2;
//while (aux < interval)
//{
// aux = interval*i;
// i=i+1;
// threadStartNums.Add(aux);
//}
int startNum = 0;
for (int i = 0; i < nrThreads; i++)
{
var _thread = new System.Threading.Thread(() => MarkPrimes(startNum, Math.Min(startNum + interval, nrNums), i));
startNum = startNum + interval;
//set the thread to run in the background
_thread.IsBackground = true;
//start our thread
_thread.Start();
}
while (!AllThreadsFinished())
{
Thread.Sleep(1);
}
for (int i = 0; i < nrNums; i++)
if(nums[i])
Console.WriteLine(i);
}
}
}
これは、並列に動作するnrThreads
スレッドを使用して最初のnrNums
素数を見つけて出力することになって、かなり簡単なプログラムでなければなりません。
だから、私はちょうどnrThreads
等しいチャンクにnrNums
を分割(ウェル、最後のものは等しくならない。nrThreads
をnrNums
除算しない場合、それはまた、コースの残りの部分を含むであろう)。
私はnrThreads
スレッドを開始します。
これらのすべてはそれぞれのチャンク内の各番号をテストし、プライムであるかどうかを確認します。彼らはすべての素数のタブを保持するブール配列ですべてをマークします。
スレッドはすべて、完了すると別のブール値配列ThreadsFinished
の特定の要素をtrueにします。
今、奇妙な部分が始まります。
スレッド決してすべて終了。私がデバッグした場合、私はThreadNr
が私がループでそれに割り当てるものではなく、別の値であることが分かります。 スレッドは後で実行され、カウンター(変数i)はすでにそれまでに増加しているので、これは正常ですが、コードを正しくする方法を理解できません。
誰でも手助けできますか?
ありがとうございます。
P .:私はアルゴリズムがあまり効率的ではないことを知っています。私はEratosthenesのふるいを使ってxスレッドを使うという解決策を目指しています。しかし、今のところ私はこれを動作させることさえできず、私が理解できる言語のどこにでもそのアルゴリズムの実装の例は何も見つかりませんでした。
だけで簡単にドライブバイコメント:代わりに '()'偽でAllThreadsFinished、あなたは[参加]する必要がありながら、ループの(http://msdn.microsoft.com/en-us/library/95hbf2ta。 aspx)を各スレッドごとに1つずつ実行します。各呼び出しは、それぞれのスレッドが終了するまでブロックします。これは、スレッドが終了するのを待つCPU効率の良い方法です。 – cdhowie
エラトステネスのふるいは並列化できません:素数が1つあり、それは素数ではないとみなされます。あなたは次のマークされていない番号に移動し、素数で繰り返しているので、それを印刷します。 2つの別々のスレッドは何をしますか? –
@コスミン・プランズそれは、ここにhttp://cs-alb-pc3.massey.ac.nz/notes/59735/seminars/01077635.pdfと書くことができ、アルゴリズムを与えることができます。私は多くの問題を研究していませんでしたが、私はそれを非並列的にしか実装していませんでした。私は素数を見つける最速の方法の一つであることを知っていたので、私はそれを言いました。 – Para