2016-10-27 10 views
0

ユーザーが書き込むすべての番号を最初から最後まで印刷するためにコードを書きます。私はスレッドでこれをやりたいたとえば、beginは1、endは100です。ユーザに、プログラムが作成するスレッドの数であるN数を入力するよう依頼します。たとえば、彼が10に入ると、プログラムは10スレッドを作成します。最初のスレッドは1から10までの素数を出力します。2番目のスレッドは10から20までの素数を出力します.030から30と3番目のスレッドはスレッド番号の素数

です。実際には、私のプログラムは、素数ではないファイル内の多くの数値を出力します。それより多くの場合、コード内で何度も同じ数のコードを持っています。

これは私のコードです:メインで

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

'if(i%j!= 0)'が正しく表示されない – NathanOliver

+0

@AlgirdasPreidžiusエラーを解決するのに役立つもの。 –

答えて

1

あなたのコードで修正することがたくさんあり、素数は0ではなく1から始まります。また、休憩を取った後、1または0(0で割り切れません)ではなく2で割り切ってください。 1のために、それは首相ではなく、それは常にあなたが計算したいものの数で終了します(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; 
} 

はまた、ミューテックスを追加しました。

+0

ありがとうございます。しかし、私はj + 1 == iとは何か分かりません。そして、なぜ単純なelseの代わりにelseを書くのですか? –

+0

テストする最後の要素はj + 1になります。他のすべてのテストが合格で素数であるため、そこに到達した場合はj + 1になります。 – cpatricio

+0

私は非常によく理解していないので私に例を与えることができます –

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と割り切れない場合のためのものである。しかし、それは素数ではない。)、それは任意の数で割り切れない場合

数が素数である(> = 2 )、それが割り切れない数があればそうではありません。

beginend/2の間の要因を調べるには、2sqrt(end)の間を探す必要もあります。

私がアドバイスをしているのは、マルチスレッドとインターバルスライスを開始する前に、動作中のシングルスレッド素数性テストを最初に書くことです。