当前位置:  开发笔记 > 编程语言 > 正文

Prime数字生成器使用线程

如何解决《Prime数字生成器使用线程》经验,为你挑选了1个好方法。

我试图在C#中使用Threads生成素数.用户必须输入要生成的线程数.运行代码时出现以下问题:

    如果我尝试使用多个线程,有时会使Index超出范围异常.如果我再试一次,它会起作用.

    每个线程都在计算相同的值.例如,如果我输入两个线程来生成2到100之间的素数(包括两者),我得到以下输出.

2 3 5 7 11 13 17 19 23 29 31 37 41 43 47 2 3 5 7 11 13 17 19 23 29 31 37 41 43 47

我已经完成了以下帖子.但我无法解决这些问题.我是线程概念的新手.如何解决这些问题?

简单的素数程序 - 线程C#的奇怪问题

这是我的代码

class Program {
  const int min = 2;
  const int max = 100;
  static List primes = new List ();

  static void GeneratePrimes (int start, int range) {
     bool isPrime = true;
     int end = start + range;
     for (int i = start; i <= end; i++) {
        for (int j = start; j <= end; j++) {
           if (i != j && i % j == 0) {
              isPrime = false;
              break;
           }
        }
        if (isPrime) {
           primes.Add (i);
        }
        isPrime = true;
     }
  }

  static void Main (string[] args) {
     int threadCount = Convert.ToInt32 (Console.ReadLine ());
     Thread[] threads = new Thread[threadCount];
     int range = (max - min) / threadCount;
     int start = min;         
     for (int i = 0; i < threadCount; i++) {
        int startl = start;
        threads[i] = new Thread(new ThreadStart(() => GeneratePrimes(start, range)));
        startl += range;
        threads[i].Start ();            
     }
     for (int i = 0; i < threadCount; i++)
        threads[i].Join();
     PrintPrimes();
  }

  static void PrintPrimes () {
     foreach (int i in primes)
        Console.WriteLine (i);
  }
}

UPDATE

我根据NikolayKondratyev的回答提出了改变.但是当我使用更多线程时,我现在在列表中有重复的值(> 5)



1> NikolayKondr..:

第一个问题是你start的线程错了.线程创建应该是

for (int i = 0; i < threadCount; i++) {
    var startl = start;
    threads[i] = new Thread(new ThreadStart(() => GeneratePrimes(startl, range)));
    start += range;
    threads[i].Start();
}

另外List是不是线程安全的,insted的使用线程安全集合.例如ConcurrentQueue及其方法Enqueue.

for条件也有问题,应该如下

for (var i = start; i < end; i++)
{
    for (var j = min; j < end; j++)
    {
        ...
    }
}

你可以用它来优化它

for (var j = min; j < Math.Sqrt(end); j++)

另一个问题是你有错误的范围,可能有未处理的值,因为例如start + range 小于max5个线程.因此,对于最后一个线程,我们需要添加(max - min)%threadCount 更多值.这是完整的代码

class Program
{
    private const int min = 2;
    private const int max = 100;
    private static readonly ConcurrentQueue primes = new ConcurrentQueue();

    private static void GeneratePrimes(int start, int range)
    {
        var isPrime = true;
        var end = start + range;
        for (var i = start; i < end; i++)
        {
            for (var j = min; j < Math.Sqrt(end); j++)
            {
                if (i != j && i%j == 0)
                {
                    isPrime = false;
                    break;
                }
            }
            if (isPrime)
            {
                primes.Enqueue(i);
            }
            isPrime = true;
        }
    }

    private static void Main(string[] args)
    {
        var threadCount = Convert.ToInt32(Console.ReadLine());
        var threads = new Thread[threadCount];
        var range = (max - min)/threadCount;
        var start = min;
        for (var i = 0; i < threadCount - 1; i++)
        {
            var startl = start;
            threads[i] = new Thread(() => GeneratePrimes(startl, range));
            start += range;
            threads[i].Start();
        }
        threads[threadCount - 1] = new Thread(() => GeneratePrimes(start, range + (max - min)%threadCount));
        threads[threadCount - 1].Start();

        for (var i = 0; i < threadCount; i++)
            threads[i].Join();
        PrintPrimes();
    }

    private static void PrintPrimes()
    {
        foreach (var i in primes)
            Console.WriteLine(i);
    }
}

推荐阅读
重庆制造漫画社
这个屌丝很懒,什么也没留下!
DevBox开发工具箱 | 专业的在线开发工具网站    京公网安备 11010802040832号  |  京ICP备19059560号-6
Copyright © 1998 - 2020 DevBox.CN. All Rights Reserved devBox.cn 开发工具箱 版权所有