Это мой код:
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);
}
}
}
Это должна быть довольно простая программа, которая должна находить и выводить первые nrNums
простые числа с использованием потоков nrThreads
, работающих параллельно.
Итак, я просто разделил nrNums
на nrThreads
равных кусков (ну, последний не будет равен; если nrThreads
не делится на nrNums
, он также будет содержать остаток, курс).
Я запускаю nrThreads
темы.
Все они проверяют каждое число в соответствующем куске и проверяют, простое оно или нет; они помечают все в массиве bool, в котором хранятся все простые числа.
Все потоки превращают определенный элемент в другом логическом массиве ThreadsFinished
в истину, когда они заканчивают.
Теперь начинается странная часть:
Потоки никогда не заканчиваются. Если я отлаживаю, я обнаружил, что ThreadNr
- это не то, что я назначаю ему в цикле, а другое значение.
Я предполагаю, что это нормально, поскольку потоки выполняются впоследствии, и к тому времени счетчик (переменная i) уже увеличивается, но я не могу понять, как сделать код правильным.
Может кто-нибудь помочь?
Заранее спасибо.
П.С .: Я знаю, что алгоритм не очень эффективен; Я стремлюсь к решению, используя сито Eratosthenes также с x заданными нитями. Но сейчас я даже не могу заставить его работать, и я не нашел примеров реализации этого алгоритма нигде на понятном мне языке.