曲径通幽论坛

 找回密码
 立即注册
搜索
查看: 5738|回复: 0
打印 上一主题 下一主题

埃拉托色尼筛法多线程找素数

[复制链接]

4918

主题

5880

帖子

3万

积分

GROAD

曲径通幽,安觅芳踪。

Rank: 6Rank: 6

积分
34397
跳转到指定楼层
楼主
发表于 2010-10-20 22:36:34 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
埃拉托色尼筛法
利用埃拉托色尼筛法寻找 2~n 之间的素数,方法是去掉所有 2 的倍数,再去掉所有 3 的倍数,以此类推,最后剩下的就是素数。

下面程序使用多线程来完成:

include <stdio.h>
#include <math.h>
#include <pthread.h>
#define MAX_N           100000000
#define MAX_THREADS     100
int nthreads, n, prime[MAX_N + 1], nextbase;
int work[MAX_THREADS];
pthread_mutex_t nextbaselock = PTHREAD_MUTEX_INITIALIZER;
pthread_t id[MAX_THREADS];
void crossout (int k)
{
        int i;
        for (i = k; i*k <= n; i++) {    //最小为该数的平方,然后是依次向上为该数的倍数(3*3,3*4,3*5...)
                prime[i*k] = 0;
        }
}
void *worker (void *unuse)
{
        int lim, base;
        lim = sqrt(n);  //最大值的平方根为最大基数
   do {
        pthread_mutex_lock (&nextbaselock);
        base = nextbase += 2;           //每个线程都有自己的局部变量,但nextbase是全局变量,会被所有线程共享,所以此处需要互斥锁保护
        pthread_mutex_unlock (&nextbaselock);
        if (base <= lim) {
            if (prime[base])
                crossout(base);
        } else return;
   } while (1);
}
int main (int argc, char **argv)
{
        int nprimes, i;
        if (argc != 3) {
           printf ("usage: %s threads range
", argv[0]);
           return (-1);
        }
        n = atoi (argv[1]);
        if (n >= MAX_N) {
            printf ("out of range
");
            return (-1);
        }
        nthreads = atoi (argv[2]);
        if (nthreads > 100) {
            printf ("out of range
");
            return (-1);
        }
        for (i = 2; i <= n; i++) //将所有数填充到数组
            prime[i] = i;
        crossout(2);    //2为素数,其余倍数不为素数
        nextbase = 1;
        for (i = 0; i < nthreads; i++) {
            pthread_create (&id[i], NULL, (void *)worker, NULL);
        }
        for (i = 0; i < nthreads; i++) {
            pthread_join (id[i], NULL);
        }
        for (i = 0; i < n; i++) {
                if (prime[i] != 0)
                   printf ("%d  ", prime[i]);
        }
        printf ("
");
        return (0);
}

编译


gcc -g debug_pthread.c -lpthread -lm -o debug_pthread


运行与输出


debug_pthread 100 5
2  3  5  7  11  13  17  19  23  29  31  37  41  43  47  53  59  61  67  71  73  79  83  89  97

用 5 个线程求 100 内的所有素数。
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

小黑屋|手机版|Archiver|曲径通幽 ( 琼ICP备11001422号-1|公安备案:46900502000207 )

GMT+8, 2025-6-17 19:15 , Processed in 0.078647 second(s), 22 queries .

Powered by Discuz! X3.2

© 2001-2013 Comsenz Inc.

快速回复 返回顶部 返回列表