簡體   English   中英

多線程素數生成器

[英]Multithreaded prime number generator

我有:

input1: n to generate primes up to
input2: no of threads to generate primes

我實現了它,並且它起作用了,但是問題是,每個線程都生成自己的素數列表[2, n]

但是我希望兩個線程都在完成生成質數,彼此切換而不是獨立進行的同一任務上工作。 如何將n划分為線程數?

#include <pthread.h>
#include <stdio.h>
#include <stdlib.h>
#include <math.h>

void *BusyWork(void *threadid)
{
long tid;
tid = (long)threadid;
printf("Hello World! It's me, thread # %ld\n", tid);

double s,d;
int n,i,c,k,p,cs,nsqrt;     
printf( "Input an integer n > 1 to generate primes upto this n:   " ); // prompt 
scanf("%d",&n); 
printf( "Entered integer: %d\n",n);
int array[n];
for(i=0;i<n;i++)
    array[i]=0;
s=sqrt(n);
d=floor(s);
nsqrt = (int) d;

for ( c= 2; c <= nsqrt; c++ )// note here < is not working <= is working here.
    {
        if(array[c]==0)
            {
                cs = c*c;
                k=0;
                for(p=cs; p<n; p=(cs+k*c))
                    {
                        k++;
                        array[p] = 1;
                }//for
            }//if
    }//for

    for ( i = 2; i < n; i++ )
    { 
        if (array[i]==0)
        {
            printf("%5d",i);
        }//if
    }// for
    printf("\n");


    printf("Above prime numbers are generated from me i.e. thread # %ld GOOD BYE!!! \n ", tid);


    pthread_exit((void*) threadid);
    }

  int main (int argc, char *argv[])
  {

   //////// time cal ///////////////////

     struct timespec start, finish;
     double elapsed;

      clock_gettime(CLOCK_MONOTONIC, &start);
     /////////////////////////////////////

    int NUM_THREADS;
     printf("Please Input Total Number of Threads you want to make:-  ");
     scanf("%d",&NUM_THREADS);


     pthread_t thread[NUM_THREADS];
     pthread_attr_t attr;
       int rc;
     long t;
     void *status;

       /* Initialize and set thread detached attribute */
     pthread_attr_init(&attr);
       pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_JOINABLE);

      for(t=0; t<NUM_THREADS; t++) {
        printf("Main: creating thread %ld\n", t);
        rc = pthread_create(&thread[t], &attr, BusyWork, (void *)t); 
        if (rc) {
           printf("ERROR; return code from pthread_create() is %d\n", rc);
           exit(-1);
          }
        }

      /* Free attribute and wait for the other threads */
       pthread_attr_destroy(&attr);
      for(t=0; t<NUM_THREADS; t++) {
       rc = pthread_join(thread[t], &status);
      if (rc) {
       printf("ERROR; return code from pthread_join() is %d\n", rc);
       exit(-1);
       }
       printf("Main: completed join with thread %ld having a status of %ld\n",t,  (long)status);
      }

  printf("Main: program completed. Exiting.\n");
   ////////////// time end ////////////////////////
    clock_gettime(CLOCK_MONOTONIC, &finish);

   elapsed = (finish.tv_sec - start.tv_sec);
      elapsed += (finish.tv_nsec - start.tv_nsec) / 1000000000.0;
   printf("Total time spent by the main:  %e \n", elapsed);
    //////////////////////////////////////////////////////////
   pthread_exit(NULL);
     }

您想要的不是一件容易的事。 但是,這里有一個思考,研究和測試兩個線程的想法。

為此,您需要在兩個線程之間“拆分”作業。 例如,使第一個線程在[ 2, k ]之間尋找素數,並使第二個線程在[ k+1, x ]之間尋找素數。

這是微不足道的部分。 問題來了-如何找到x k很容易x / 2 )。

您應該研究-例如如何查找給定間隔中的質數。 可能很有用:它說,您可以使用:

N ~~ x / ln(x)

其中N是素數,小於x。

好吧,我不是數學家,現在不能給您解決方案,但是應該有一種方法,讓N找到x

請注意,這對於大量工作正常。

因此,有了這個,一旦找到x,就可以在兩個線程之間分配作業。

如您所見,這確實是不容易的,並且沒有精確(精確)的方法來找到xN )。


當然,另一種簡單的方法(雖然容易很多,但不是那么好)是知道N的范圍並將其分成兩個間​​隔。 或者,找到第一個,例如100個素數,沒什么大不了的。 但是找到第一個1000是另一回事。 例如,在這種情況下,您可以為每個+500質數啟動其他線程。


另一個想法是進行研究以找到第N個素數的近似值。 這可能會有所幫助: 有沒有辦法找到第n個素數的近似值?

抱歉,如果我誤解了您的帖子,但我懷疑您誤解了多線程的含義。 您的代碼和最后一個問題表明您認為啟動多個相同的線程意味着它們以某種方式自動將任務划分為兩個線程。 從根本上說這是不正確的。 我們都希望是,但不是。

有幾種方法。 有一種“手動”方法,您可以在問題中利用並行的機會,並為每個位編寫一個線程(或用不同的參數多次啟動同一線程。這兩種方法的線程與數據都不相同)。 然后,您可以並行運行這些線程。 本質上,這就是Kirol Kirov建議的方法。

對於長循環的數學問題,一種非常有效的替代方法是使用編譯器,該編譯器可以在運行時將循環自動分解為單獨的線程。 這意味着您可以編寫普通的單線程代碼,並告訴編譯器在可以確定這樣做安全的任何地方生成線程。 為您節省大量工作,並在適當的情況下產生有效的結果。 Sun C編譯器可以在Solaris上執行此操作,而Intel C編譯器也可以(可能僅在Windows上)執行此操作。 對最新和最偉大的一些研究也許是值得的。 但是,這不會教您任何有關多線程編程的知識。

另一種方法是使用類似openMPI的方法(我認為),您可以將#pragma語句放在for循環之前,以表示您希望並行執行平鋪循環。 Kinda喜歡英特爾和Sun編譯器可以做的手動版本。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM