[英]Display the prime numbers using multi-threading in C
在 function printprime
中,我用四個線程中的每一個迭代每個元素,這幾乎相當於一個單線程程序。 我想將i
增加i=i+MAX_THREADS
。 我正在使用四個線程,因為我的筆記本電腦有四個處理器並且已經過全面優化。 有人能告訴我如何調整printprime
以便每個線程迭代一個數字。 例如,線程 1 檢查 2、6、10... 線程 2 檢查 3、7、11... 等等。
#include <stdio.h>
#include <pthread.h>
#define N 30
#define MAX_THREADS 4
int prime_arr[N] = { 0 };
void *printprime(void *ptr) {
int j, flag;
int i = (int)(long long int)ptr;
for (i = 2; i < N; i++) {
flag = 0;
for (j = 2; j <= i / 2; j++) {
if (i % j == 0) {
flag = 1;
break;
}
}
if (flag == 0) {
prime_arr[i] = 1;
}
}
}
int main() {
pthread_t tid[MAX_THREADS] = {{ 0 }};
int count = 0;
for (count = 0; count < MAX_THREADS; count++) {
printf("\r\n CREATING THREADS %d", count);
pthread_create(&tid[count], NULL, printprime, (void *)count);
}
printf("\n");
for (count = 0; count < MAX_THREADS; count++) {
pthread_join(tid[count], NULL);
}
int c = 0;
for (count = 0; count < N; count++)
if (prime_arr[count] == 1)
printf("%d ", count);
return 0;
}
為了達到理想效果, void *printprime(void *ptr)
函數void *printprime(void *ptr)
的變量i
遞增MAX_THREADS
(在您的情況下為4)。
注意:行printf("Thread id[%d] checking [%d]\\n",pthread_self(),i);
用於顯示哪個線程正在檢查哪個值。
以下代碼可能會有所幫助:
#include<stdio.h>
#include<pthread.h>
#define N 30
#define MAX_THREADS 4
int prime_arr[N]={0};
void *printprime(void *ptr)
{
int j,flag;
int i=(int)(long long int)ptr;
while(i<N)
{
printf("Thread id[%d] checking [%d]\n",pthread_self(),i);
flag=0;
for(j=2;j<=i/2;j++)
{
if(i%j==0)
{
flag=1;
break;
}
}
if(flag==0 && (i>1))
{
prime_arr[i]=1;
}
i+=MAX_THREADS;
}
}
int main()
{
pthread_t tid[MAX_THREADS]={{0}};
int count=0;
for(count=0;count<MAX_THREADS;count++)
{
printf("\r\n CREATING THREADS %d",count);
pthread_create(&tid[count],NULL,printprime,(void*)count);
}
printf("\n");
for(count=0;count<MAX_THREADS;count++)
{
pthread_join(tid[count],NULL);
}
int c=0;
for(count=0;count<N;count++)
if(prime_arr[count]==1)
printf("%d ",count);
return 0;
}
您的代碼中存在多個問題:
所有線程都使用for (i = 2; i < N; i++)
所以它們執行完全相同的掃描,測試相同的數字......使用多個線程沒有任何優勢。
對於掃描質數但不打印質數的 function,名稱printprime
非常令人困惑。
您在沒有同步的情況下在多個線程中修改同一個數組:如果從不同線程訪問同一元素並且元素大小小於原子大小,則這具有未定義的行為。
即使為每個線程修改了代碼以測試您在問題中記錄的子集,這也會非常低效,因為所有其他線程最終只會測試偶數。
for (j = 2; j <= i / 2; j++)
的循環對於素數來說迭代的時間太長了。 你應該在j * j > i
時停止,這可以通過for (j = 2; i / j <= j; j++)
來測試。
即使進行了這種優化,試驗除法填充prime_arr
數組的效率也非常低。 實施埃拉托色尼篩法要優越得多,也更適合多線程方法。
這是一個例子:
#include <stdio.h>
#include <stdint.h>
#include <pthread.h>
#define N 10000000
#define MAX_THREADS 4
unsigned char prime_arr[N];
void *scanprime(void *ptr) {
int n, i, j, flag, start, stop;
n = (int)(intptr_t)ptr;
start = N / MAX_THREADS * n;
stop = N / MAX_THREADS * (n + 1);
if (start < 2)
start = 2;
if (n == MAX_THREADS - 1)
stop = N;
for (i = start; i < stop; i++) {
flag = 1;
for (j = 2; i / j >= j; j++) {
if (i % j == 0) {
flag = 0;
break;
}
}
prime_arr[i] = flag;
}
return NULL;
}
void *sieveprimes(void *ptr) {
int n, i, j, start, stop;
n = (int)(intptr_t)ptr;
/* compute slice boundaries */
start = N / MAX_THREADS * n;
stop = N / MAX_THREADS * (n + 1);
/* special case 0, 1 and 2 */
if (n == 0) {
prime_arr[0] = prime_arr[1] = 0;
prime_arr[2] = 1;
start = 3;
}
if (n == MAX_THREADS - 1) {
stop = N;
}
/* initialize array slice: only odd numbers may be prime */
for (i = start; i < stop; i++) {
prime_arr[i] = i & 1;
}
/* set all multiples of odd numbers as composite */
for (j = 3; j * j < N; j += 2) {
/* start at first multiple of j inside the slice */
i = (start + j - 1) / j * j;
/* all multiples below j * j have been cleared already */
if (i < j * j)
i = j * j;
/* only handle odd multiples */
if ((i & 1) == 0)
i += j;
for (; i < stop; i += j + j) {
prime_arr[i] = 0;
}
}
return NULL;
}
int main() {
pthread_t tid[MAX_THREADS] = { 0 };
int i;
for (i = 0; i < MAX_THREADS; i++) {
printf("Creating thread %d\n", i);
pthread_create(&tid[i], NULL, sieveprimes, (void *)(intptr_t)i);
}
for (i = 0; i < MAX_THREADS; i++) {
pthread_join(tid[i], NULL);
}
int count = 0;
for (i = 0; i < N; i++) {
count += prime_arr[i];
//if (prime_arr[i] == 1)
// printf("%d\n", i);
}
printf("%d\n", count);
return 0;
}
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.