带线程的素数

时间:2016-10-27 14:34:10

标签: c++ multithreading

我编写代码以便从用户写入的开头到结尾打印所有数字。我想用线程来做这件事。例如,begin为1,end为100.我要求用户输入一个N数字,它是程序创建的线程数。例如,如果他输入10,程序将创建10个线程。第一个线程将打印从1到10的素数。第二个线程将打印从10到20的素数。第三个从20到30和儿子...

但我有一个问题。事实上,我的程序在文件中打印了许多不是素数的数字,而且在代码中我经常会多次使用相同的数字。

这是我的代码:

void writePrimesToFile(int begin, int end, ofstream&  file)
{
    for (int i = begin; i <= end; i++)
    {
        for (int j = begin; j < end / 2; j++)
        {
            if (i % j != 0)
            {
                file << i << endl;
            }

        }
    }
}

void callWritePrimesMultipleThreads(int begin, int end, string filePath, int N)
{
    ofstream myfile(filePath);
    clock_t startTimer, stopTimer;

    startTimer = clock();

    vector<thread> arr;

    for (int i = 0; i < N; i++)
    {
        int start = begin;
        int finish = N;
        arr.emplace_back(writePrimesToFile, start, finish, ref(myfile));
        start = finish;
        finish += N;
    }
    for (auto& thread : arr)
    {
        thread.join();
    }

    stopTimer = clock();
    cout << "The time that takes is: " << (double)(stopTimer - startTimer) / CLOCKS_PER_SEC << endl;
}

主要代码:

    callWritePrimesMultipleThreads(1, 100, "primes2.txt", 10);

2 个答案:

答案 0 :(得分:1)

你的代码中需要修复很多东西,素数将从1开始,而不是0,你也应该开始除以2而不是1或0(你不能除以0),在你休息之后0为一,它不是素数,它总是以你想要计算的数量结束(10%20是无意义的)

#include <stdio.h>
#include <iostream>
#include <thread>
#include <mutex>
#include <vector>
#include <functional>
#include <fstream>
#include <math.h>

using namespace std;
mutex mtx;

void writePrimesToFile(unsigned int begin, unsigned int end, ofstream& f)
{
    for (unsigned int i = begin; i <= end; i++)
    {
        for (unsigned int j = 2; j < i; j++)
        {
            if (i % j == 0)
            {
                break;
            }
            else if(j + 1 == i)
            {
                mtx.lock();
                f << i << endl;
                mtx.unlock();
            }
        }
    }
}

void callWritePrimesMultipleThreads(unsigned int begin, unsigned int end, string filePath, unsigned int N)
{
    ofstream myfile(filePath);
    clock_t startTimer, stopTimer;

    startTimer = clock();

    vector<thread> arr;
    unsigned int each = end/N;
    unsigned int start = begin;
    unsigned int finish = start + each - 1;
    for (unsigned int i = 0; i < N; i++)
    {
        arr.emplace_back(writePrimesToFile, start, finish, ref(myfile));
        start += each;
        finish += each;
    }
    for (auto& thread : arr)
    {
        thread.join();
    }

    stopTimer = clock();
    cout << "The time that takes is: " << (double)(stopTimer - startTimer) / CLOCKS_PER_SEC << endl;
}


int main()
{
    callWritePrimesMultipleThreads(1, 110, (string)"primes.txt", 10);
    return 0;
}

此外,在写入文件时添加了一个互斥锁。

答案 1 :(得分:0)

看看你的循环:

for (int i = begin; i <= end; i++)
{
    for (int j = begin; j < end / 2; j++)
    {
        if (i % j != 0)
        {
            file << i << endl;
        }

    }
}

您每次输出i 找到一个不可分割的数字。
这是很多数字 (例如,9不能用2,4,5,6,7或8整除。但它不是素数。)

如果数字不能被任何数字(&gt; = 2)整除,则数字为素数,而不是如果有任何数字则不能将其整除。

beginend / 2之间查找因素也是不够的,您需要在2sqrt(end)之间查看。

我的建议是在开始多线程和间隔切片之前先编写一个有效的单线程素数测试。