我目前正在研究这个多线程素数生成器,它计算 2 - N 之间的素数数量,目前每个线程计算所有素数,看起来线程一个接一个地运行,但我希望所有线程同时运行。
现在我想问一下如何告诉线程它应该只计算切片大小,而不是所有素数和"t"线程同时运行。
例如:2-1000 有四个线程 ->每个线程应该计算 250 个数字
提前感谢!
这是我目前所拥有的:
#include <stdio.h>
#include <time.h>
#include <pthread.h>
#include <stdlib.h>
#include <unistd.h>
#include <errno.h>
/* compile: gcc prime.c -lpthread -o prime */
/* execute: ./prime -N 1000 -t 8 */
pthread_mutex_t aktuell_lock = PTHREAD_MUTEX_INITIALIZER;
int N;
int Primzahlen;
int aktuell = 2;
int t;
//int slicesize = N/t;
void print_usage(void)
{
printf("Usage: prime -N <value> -t <value>n");
}
void *prime(void *a)
{
int Laufvariable;
int i;
pthread_mutex_lock(&aktuell_lock);
for (i = 0; i < N/t; i++) {
for (aktuell; aktuell <= N; aktuell++) {
for (Laufvariable = (aktuell-1); aktuell % Laufvariable; Laufvariable--) {
}
if (Laufvariable == 1)
Primzahlen++;
}
}
pthread_mutex_unlock(&aktuell_lock);
return NULL;
}
int main(int argc, char *argv[])
{
struct timespec start, finish;
double elapsed;
clock_gettime(CLOCK_MONOTONIC, &start);
int s;
int option;
while ((option = getopt(argc, argv, "N:t:")) != -1)
switch (option) {
case 'N':
N = atoi(optarg);
break;
case 't':
t = atoi(optarg);
break;
default:
print_usage();
exit(EXIT_FAILURE);
}
pthread_t threads[t];
for (s = 0; s < t; s++) {
pthread_create(&threads[t], NULL, prime, NULL);
}
void *result;
for (s = 0; s < t; s++) {
pthread_join(threads[t], &result);
}
clock_gettime(CLOCK_MONOTONIC, &finish);
elapsed = (finish.tv_sec - start.tv_sec);
elapsed += (finish.tv_nsec - start.tv_nsec) / 1000000000.0;
printf("nCount Primes [1 .. %d] - TaskCnt: %d - Slicesize: %dn", N, t, N / t);
printf("Threads: %dn", t);
printf("limit: %dn", N);
printf("Total Prime Count: %dn", Primzahlen);
printf("Runtime: %f secondsnn", elapsed);
return 0;
}
使用锁进行并行处理绝对不会妨碍可扩展的程序。
与其在锁下的全局变量中累积结果和状态,不如尝试累积特定于线程的部分结果,然后合并它们。
有现成的可扩展素数计数器示例,它驻留在 tbb 分布中。您可以直接使用它,也可以采用工作范围划分和减少部分结果的想法,并在您的要求下以简单的C
实施它。
您可以分阶段执行此操作。最简单的版本使用单个线程生成一个素数数组,直到 prime(i) * prime(i)>= N.Set R = N-prime(i),这是要测试的数字范围。然后线程[j](j从0开始)应该测试从prime(i)+j * (R/t)到prime(i)+(j+1) *(R/t),最后一个线程测试从prime(i)+j * (R/t)到N(t是线程数)。每个线程都会生成自己的计数,一旦所有线程完成,计数就会相加。
每个线程还可以生成自己的素数范围,一旦所有线程都完成,数组就会连接起来。这可以扩展到通过几次传递,例如查找从 2