Vừa rồi mình thấy có rất nhiều bạn hỏi về việc phân rã hàm kiểm tra số nguyên tố ra thành nhiều luồng để tận dụng tối đa khả năng của bộ xử lý nhiều nhân. Mình thấy đây là một câu hỏi cũng khá hay và cũng có thể ứng dụng được trong thực tế nên quyết định làm một tút nhỏ về việc này.
Ý tưởng là ta phân rã phạm vi tìm số nguyên tố ra làm nhiều khoảng nhỏ và giao cho nhiều luồng xử lý song song. Nếu máy chỉ có 1 nhân thì việc này thậm chí còn tốn thời gian hơn bình thường vì chi phí chuyển đổi ngữ cảnh giữa các luồng. Nhưng nếu máy có nhiều vi xử lý thì tốc độ sẽ được cải thiện đáng kể.
Để tạo thread bạn dùng hàm CreateThread, tham số lpParameter bạn nên truyền vào con trỏ tới cấu trúc gồm có 2 phần tử là min và max, đó chính là cấu trúc lưu trữ 2 biên để tìm kiếm. Ngoài ra còn phải có một biến kết quả dùng chung để sau khi các thread kết thúc ta sẽ and các kết quả lại với nhau để ra kết quả tổng hợp.
Cuối cùng là code minh họa :
Mã:
#include <windows.h>#include <math.h>#include <stdio.h>#include <conio.h> typedef struct _THREADSHAREDDATA{ unsigned long ThreadCounter; unsigned long ThreadCounterMax; // tổng số thread HANDLE hCallerThread; // handler của thread gọi unsigned long Num; // số cần kiểm tra bool Ans; // kết quả trả về } THREADSHAREDDATA; typedef struct _THREADPARAM{ unsigned long Min,Max; THREADSHAREDDATA *pSharedData;} THREADPARAM; DWORD WINAPI ThreadProc(LPVOID lpParameter){ THREADPARAM *pThreadParam = (THREADPARAM *)lpParameter; unsigned long i, min = pThreadParam->Min, max = pThreadParam->Max; unsigned long num = pThreadParam->pSharedData->Num; bool *pAns = &(pThreadParam->pSharedData->Ans); // kiểm tra số nguyên tố for (i=min;i<=max;i++) { if (((num % i) == 0) || !(*pAns)) { (*pAns) &= false; break; } } // nếu thread cuối cùng kết thúc thì resume lại main thread (pThreadParam->pSharedData->ThreadCounter)++; if (pThreadParam->pSharedData->ThreadCounter == pThreadParam->pSharedData->ThreadCounterMax) { ResumeThread(pThreadParam->pSharedData->hCallerThread); } return 0;} bool IsPrimeNum(unsigned long num){ unsigned long k = (unsigned long)sqrt(num) + 1; HANDLE hThread = OpenThread(THREAD_ALL_ACCESS,0,GetCurrentThreadId()); THREADSHAREDDATA ThreadSharedData; THREADPARAM ThreadParam1, ThreadParam2; ThreadSharedData.ThreadCounter = 0; ThreadSharedData.ThreadCounterMax = 2; // sẽ tạo ra 2 thread ThreadSharedData.hCallerThread = hThread; ThreadSharedData.Num = num; ThreadSharedData.Ans = true; ThreadParam1.Min = 2; ThreadParam1.Max = k / 2; ThreadParam1.pSharedData = &ThreadSharedData; HANDLE hThread1 = CreateThread(NULL,0,ThreadProc,&ThreadParam1,0,NULL); ThreadParam2.Min = ThreadParam1.Max + 1; ThreadParam2.Max = k; ThreadParam2.pSharedData = &ThreadSharedData; HANDLE hThread2 = CreateThread(NULL,0,ThreadProc,&ThreadParam2,0,NULL); SuspendThread(hThread); CloseHandle(hThread1); CloseHandle(hThread2); CloseHandle(hThread); return ThreadSharedData.Ans;} int main(int argc, char* argv[]){ unsigned long num; printf("Nhap so can kiem tra : "); scanf("%lu",&num); if (IsPrimeNum(num)) printf("%lu la so nguyen to.
",num); else printf("%lu khong phai la so nguyen to.
",num); getch(); return 0;}
View more random threads:
Dưới ánh nắng mặt trời đang lên, những đống pallet nhựa An Giang trải dài mênh mông như những bức tranh tự nhiên đầy sắc màu. Mỗi chiếc pallet nhựa không chỉ là một vật dụng thông thường mà còn là...
Pallet nhựa An Giang giao hàng...