如何为多线程分块素数?
How do I chunk prime numbers for multithreading?
我是 C 的新手,到目前为止几乎没有多线程方面的经验。我写了一个小程序来计算一组数字是素数还是合数。这工作正常,但是当处理更大的数字时,我想在线程之间分配工作负载。
我有点知道这是如何工作的,我只是看不出如何在 C 中实现它。作为一个简单的例子,如果我们取素数 199,我会将这个数字除以核心(例如 4)得到 49.75。然后我们将这个数字四舍五入为 50。然后每个线程将被赋予一个范围来计算。
第一个线程将从 i 2 计算到 50,第二个线程将从 i 51 计算到 102,依此类推。
我希望这是有道理的,我确信解决方案比我想象的要简单,只是我一辈子都无法解决。
我的代码:
#include <pthread.h>
#include <inttypes.h>
#include <stdio.h>
#include <unistd.h>
#ifdef _SC_NPROCESSORS_ONLN
#define NUM_THREADS sysconf(_SC_NPROCESSORS_ONLN)
#else
#define NUM_THREADS 1
#endif
uint64_t numbers[] = {7,3,19,17,199,333}; // Numbers to check
void *work(void *n_void_ptr);
int isPrime(uint64_t n);
int main()
{
int rc;
pthread_t thread[NUM_THREADS];
for (int i = 0; i < sizeof(numbers) / sizeof(uint64_t); i++) {
rc = pthread_create(&thread[i], NULL, work, &numbers[i]);
}
pthread_exit(NULL);
return 0;
}
void *work(void *n_void_ptr)
{
uint64_t *n_ptr = (uint64_t *)n_void_ptr;
if (!isPrime(*n_ptr)) {
printf("%llu is a prime!\n", *n_ptr);
}
pthread_exit(NULL);
}
int isPrime(uint64_t n)
{
int count = 0;
uint64_t i; // Any number > n/2 cannot be a factor
for (i = 2; i < n / 2 - 0.5; i++) {
if (n % i == 0) {
count++;
}
if (count == 1) {
printf("%llu is composite!\n", n);
return -1; // n is not prime
}
}
return 0; // n is prime
}
所以你要做的是用不同的线程来检查不同的非重叠范围。
我们首先需要一个结构来将范围传递给工人。所以我们从 -
开始
typedef struct {
int lower;
int upper;
int number;
int result;
} worker_range;
现在主要假设您需要检查 199 个值,每个线程需要检查 50 个值。
我们这样开始
worker_threads **ranges = malloc(sizeof(worker_threads*) * (199 / 50 + 1));
现在我们需要生成线程
int i;
for ( i = 0; i < 199 / 50 + 1; i++){ //Fix this so that extra threads are not spawned.
ranges[i] = malloc(sizeof(worker_range));
ranges[i]->number = 199;
ranges[i]->lower = 2 + i * 50;
ranges[i]->upper = range->lower + 50; //We are probably okay with a bit of overflow
range[i]->result = 0;
pthread_create(&thread[i], NULL, work, ranges[i]);
}
现在所有线程都已启动,我们等待它们完成。
int flag = 0;
for ( i = 0 ;i < 199 / 50 + 1; i++) {
pthread_join(thread[i]);
if(ranges[i]->result == 1)
flag = 1;
free(ranges[i]);
}
if (flag==1){
printf("%d is composite\n",199);
}else{
printf("%d is prime\n",199);
}
free(ranges);
最后是worker函数-
void* work(void * param) {
work_range *range = param;
int i;
for(i = range->lower, i < range->upper; i++){
if (range->number % i == 0){
(range->result) = 1;
break;
}
}
}
希望对您有所帮助。
我是 C 的新手,到目前为止几乎没有多线程方面的经验。我写了一个小程序来计算一组数字是素数还是合数。这工作正常,但是当处理更大的数字时,我想在线程之间分配工作负载。
我有点知道这是如何工作的,我只是看不出如何在 C 中实现它。作为一个简单的例子,如果我们取素数 199,我会将这个数字除以核心(例如 4)得到 49.75。然后我们将这个数字四舍五入为 50。然后每个线程将被赋予一个范围来计算。
第一个线程将从 i 2 计算到 50,第二个线程将从 i 51 计算到 102,依此类推。
我希望这是有道理的,我确信解决方案比我想象的要简单,只是我一辈子都无法解决。
我的代码:
#include <pthread.h>
#include <inttypes.h>
#include <stdio.h>
#include <unistd.h>
#ifdef _SC_NPROCESSORS_ONLN
#define NUM_THREADS sysconf(_SC_NPROCESSORS_ONLN)
#else
#define NUM_THREADS 1
#endif
uint64_t numbers[] = {7,3,19,17,199,333}; // Numbers to check
void *work(void *n_void_ptr);
int isPrime(uint64_t n);
int main()
{
int rc;
pthread_t thread[NUM_THREADS];
for (int i = 0; i < sizeof(numbers) / sizeof(uint64_t); i++) {
rc = pthread_create(&thread[i], NULL, work, &numbers[i]);
}
pthread_exit(NULL);
return 0;
}
void *work(void *n_void_ptr)
{
uint64_t *n_ptr = (uint64_t *)n_void_ptr;
if (!isPrime(*n_ptr)) {
printf("%llu is a prime!\n", *n_ptr);
}
pthread_exit(NULL);
}
int isPrime(uint64_t n)
{
int count = 0;
uint64_t i; // Any number > n/2 cannot be a factor
for (i = 2; i < n / 2 - 0.5; i++) {
if (n % i == 0) {
count++;
}
if (count == 1) {
printf("%llu is composite!\n", n);
return -1; // n is not prime
}
}
return 0; // n is prime
}
所以你要做的是用不同的线程来检查不同的非重叠范围。
我们首先需要一个结构来将范围传递给工人。所以我们从 -
开始typedef struct {
int lower;
int upper;
int number;
int result;
} worker_range;
现在主要假设您需要检查 199 个值,每个线程需要检查 50 个值。
我们这样开始
worker_threads **ranges = malloc(sizeof(worker_threads*) * (199 / 50 + 1));
现在我们需要生成线程
int i;
for ( i = 0; i < 199 / 50 + 1; i++){ //Fix this so that extra threads are not spawned.
ranges[i] = malloc(sizeof(worker_range));
ranges[i]->number = 199;
ranges[i]->lower = 2 + i * 50;
ranges[i]->upper = range->lower + 50; //We are probably okay with a bit of overflow
range[i]->result = 0;
pthread_create(&thread[i], NULL, work, ranges[i]);
}
现在所有线程都已启动,我们等待它们完成。
int flag = 0;
for ( i = 0 ;i < 199 / 50 + 1; i++) {
pthread_join(thread[i]);
if(ranges[i]->result == 1)
flag = 1;
free(ranges[i]);
}
if (flag==1){
printf("%d is composite\n",199);
}else{
printf("%d is prime\n",199);
}
free(ranges);
最后是worker函数-
void* work(void * param) {
work_range *range = param;
int i;
for(i = range->lower, i < range->upper; i++){
if (range->number % i == 0){
(range->result) = 1;
break;
}
}
}
希望对您有所帮助。