c - 使用 C 中的多线程进行长数素数检测
问题描述
问题陈述:检测一个长整数是否是素数。
我的逻辑:
这个想法是从 0 迭代到 sqrt(n)。如果在 0 到 sqrt(n) 之间没有找到除数,那么我可以得出结论,该数字是素数,否则是非素数。
因为,这需要多线程,所以我创建了一个名为void* PrimeDetecter(void* param);
. 在这个线程函数中,我将从startIndex
to迭代endIndex
,如果有一个除数,则退出线程并将值 1 写入到isNum1Prime
默认设置为 0 的变量地址中的状态为真。
因此,在主函数中,我需要在创建线程时将要检查的数字、开始索引和结束索引发送给线程。所以我的结构将包含long int number, startIndex, endIndex, *divisor
and int isPrime
。
然后我创建一个大小为 10 的 NumberPrime 类型的数组,因为有 10 个线程,因此将迭代平均划分。
我打印了线程之间的索引分布,效果很好。然后我只是创建线程并将所有这些元素发送到线程以检查数字是否为素数。
这是我的代码:
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#include <unistd.h>
#include <math.h>
#include <pthread.h>
#define MAX_NUM_THREADS 10 // Exercise 1: Not more than 10 threads can run at a time for example.
struct NumberPrime
{
long int number, startIndex, endIndex, *divisor;
int *isPrime;
};
void *PrimeDetector(void *param)
{
struct NumberPrime parameters = *(struct NumberPrime *)param;
for (long int i = parameters.startIndex; i < parameters.endIndex; i++)
{
if (i == 0 || i == 1)
{
break;
}
else
{
if ((parameters.number % i) == 0) // if the divisor is detected then number is not a prime
{
*(parameters.divisor) = i;
*(parameters.isPrime) = 1; // change the value to true
pthread_exit(0); // exit the thread function
}
}
}
}
int main(int argc, char *argv[])
{
long int number1 = 12340000, number2 = 128;
struct NumberPrime primeData1[MAX_NUM_THREADS];
int isNum1Prime = 0; // false
long int number1Divisor = 0;
long int numberSquareRoot1 = (long int)(sqrt(number1)); // get the square root of number1
for (int i = 0; i < MAX_NUM_THREADS; i++)
{
primeData1[i].number = number1;
primeData1[i].isPrime = &isNum1Prime;
primeData1[i].divisor = &number1Divisor;
primeData1[i].startIndex = i * numberSquareRoot1 / MAX_NUM_THREADS;
primeData1[i].endIndex = ((i + 1) * numberSquareRoot1) / MAX_NUM_THREADS;
}
pthread_t primeDetectorThread1[MAX_NUM_THREADS];
int count = 0;
for (int i = 0; i < MAX_NUM_THREADS; i++)
{
if (isNum1Prime == 1)
{
pthread_cancel(primeDetectorThread1[i]);
break;
}
else
{
pthread_create(&primeDetectorThread1[i], NULL, &PrimeDetector, &primeData1[i]);
count++;
}
}
for (int i = 0; i < count; i++)
{
pthread_join(primeDetectorThread1[i], NULL);
}
isNum1Prime == 1 ? printf("Number 1 is prime.\n") : printf("Number 1 is not prime and divisible by %ld\n", number1Divisor);
return EXIT_SUCCESS;
}
预期的输出是该数字不是素数。但无论我选择什么数字,我总是认为这个数字是素数。
解决方案
该行if ((parameters.number % i) == 0)
测试一个数字是否能被 整除i
。如果它是可整除的,则该数字不是素数,但您的代码会继续设置*(parameters.isPrime) = 1;
和结束线程。
推荐阅读
- python - 无法连接到在 AWS Ubuntu EC2 上运行的 django 应用程序
- syncfusion - 打开 ZIP 文件时出现 Zip 异常错误的 CRC 值 - Syncfusion
- azure-devops - 在推送之前测试 devops 管道中的 Nuget 包版本冲突
- google-maps - Google 地方信息自动完成 - 类型:地理编码、地址、机构 - 无法正常工作
- javascript - 画布描边和填充颜色
- groovy - 无法使用 Groovy 将 java 代码从 Eclipse 运行到 Jmeter
- javascript - Cognito 用户池“用户名”显示为 id 而不是电子邮件,如何解决?
- .net-core - 任何将 STEP 文件转换为 glTF 文件格式的开源库?
- microsoft-graph-api - 通过 Graph API 检索嵌套分发列表的邮件地址
- c# - 如何构造数据模型以绑定到具有 XML 列的 SQL 表