1

我有:

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

我实现了这个并且它可以工作,但问题是每个线程都会生成自己的 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);
     }
4

2 回答 2

4

抱歉,如果我误解了您的帖子,但我怀疑您误解了多线程的含义。您的代码和最后一个问题表明您认为启动多个相同的线程意味着它们会以某种方式自动在它们之间划分任务。这从根本上是不正确的。我们都希望是这样,但事实并非如此。

有几种方法。有一种“手动”方法,您可以利用问题中的并行性机会并为每个位编写一个线程(或使用不同的参数多次启动同一个线程。无论哪种方式线程+数据都不相同)。然后,您可以并行运行这些线程。本质上,这就是 Kirol Kirov 建议的方法。

另一种可以很好地解决长循环数学问题的替代方法是使用编译器,该编译器可以在运行时自动将循环分解为单独的线程。这意味着您编写普通的单线程代码并告诉编译器在可以确定这样做安全的地方生成线程。为您节省大量工作,并在适当的情况下产生有效的结果。Sun C 编译器可以在 Solaris 上执行此操作,而 Intel 编译器也可以执行此操作(可能仅在 Windows 上)。对最新和最伟大的研究进行一些研究可能是值得的。但是,这不会教您任何有关多线程编程的知识。

另一种方法是使用 openMPI 之类的东西(我认为)它允许您在 for 循环之前放置 #pragma 语句,以表示您希望并行执行 tile 循环。有点像 Intel 和 Sun 编译器的手动版本。

于 2013-04-01T08:04:45.497 回答
4

你想要的远非微不足道。但这里有一个思想、研究和测试两个线程的想法。

为此,您需要在两个线程之间“拆分”作业。例如,让第一个线程在 之间查找素数[ 2, k ],让第二个线程在 之间查找素数[ k+1, x ]

这是微不足道的部分。问题来了——如何找到x?(k很容易 - x / 2)。

您应该研究 - 例如,如何找到给定区间内的素数数量。可能很有用:它说,您可以使用:

N ~~ x / ln(x)

其中N是质数的个数,小于 x。

好吧,我不是数学家,我现在不能给你解决方案,但应该有办法,N必须找到x.

请注意,这适用于大量数字。

所以,有了这个,一旦你找到 x,你就可以在两个线程之间拆分工作。

如您所见,这真的远非微不足道,并且没有精确(精确)的方法来找到x( N)。


当然,另一种简单的方法(并且更容易但不是那么好)是知道范围N并将其分成两个间​​隔。或者,找到第一个,比如说,100 个素数并不是什么大问题。但是找到前 1000 个是另一回事。例如,在这种情况下,您可以为每个 +500 个素数启动额外的线程。


另一个想法是进行研究以找到N第 - 个素数的近似值。这可能会有所帮助:有没有办法找到第 n 个素数的近似值?

于 2013-04-01T07:37:48.273 回答