首先這是老師給出的定義——
靜態任務劃分:問題劃分成相對獨立的與CUP個數相等的子問題;
動態任務劃分:問題具有n(>CUP個數)個相對獨立的子問題時,尚未處理的子問題分配給空閒線程。
用實例來說明,這個例子實現了靜態任務劃分,而前幾篇文章的例子都屬於動態任務劃分。
[cpp] #include <stdio.h>
#include <pthread.h>
typedef struct myTestType
{
int threadID;
int threadNum;
int dataNum;
int *input;
int *output;
int *index;
}myTest;
int calculate(int input) {
int i;
int output = 0;
for(i=2; i<input/2; i++) {
if(input % i == 0) {
output = 1;
break;
}
}
if(output == 0)
{
sleep(1);
}
return output;
}
void thread(myTest * pMyTest) {
printf("Begin threadID=%u run!\n", pMyTest->threadID);
int input, output;
int threadID = pMyTest->threadID;
int threadNum = pMyTest->threadNum;
int dataNum = pMyTest->dataNum;
int split = dataNum / threadNum;
int firstIndex = split * threadID;
int lastIndex = firstIndex + split;
if(lastIndex > dataNum)
lastIndex = dataNum;
while(firstIndex < lastIndex) {
input = pMyTest->input[firstIndex];
output = calculate(input);
printf("index=%3u, input=%8u, output=%2u, threadID=%2u\n", firstIndex, input, output, threadID);
pMyTest->output[firstIndex] = output;
firstIndex++;
}
pthread_exit(NULL);
}
int main(void) {
int i, ret;
int threadNum = 2;
myTest * pMyTest = (myTest *)malloc(sizeof(myTest));
pMyTest->dataNum = 100;
pMyTest->input = (int *)malloc(sizeof(int)*pMyTest->dataNum);
pMyTest->output = (int *)malloc(sizeof(int)*pMyTest->dataNum);
for(i=0; i<pMyTest->dataNum;++i) {
if(i % 4 == 0)
pMyTest->input[i] = (1 << (i%30)) + 1;
else
pMyTest->input[i] = (7 << (i%16)) + 1;
}
pMyTest->index = (int *)calloc(1, sizeof(int));
pMyTest->threadNum = threadNum;
myTest * inMyTest = (myTest *)malloc(sizeof(myTest)*threadNum);
for(i=0; i<threadNum; ++i) {
memcpy(inMyTest+i, pMyTest, sizeof(myTest));
(inMyTest+i)->threadID = i;
}
pthread_t * tid = (pthread_t*)malloc(sizeof(pthread_t)*threadNum);
printf("Begin create pthread.\n");
for(i=0; i<threadNum; ++i) {
ret = pthread_create(tid+i, NULL, (void *)thread, (myTest *)(inMyTest+i));
if(ret != 0) {
printf("Create pthread error.\n");
return 0;
}
}
for(i=0; i<threadNum; i++)
pthread_join(tid[i], NULL);
free(tid);
free(inMyTest);
free(pMyTest->input);
free(pMyTest->output);
free(pMyTest->index);
free(pMyTest);
return 0;
}
#include <stdio.h>
#include <pthread.h>
typedef struct myTestType
{
int threadID;
int threadNum;
int dataNum;
int *input;
int *output;
int *index;
}myTest;
int calculate(int input) {
int i;
int output = 0;
for(i=2; i<input/2; i++) {
if(input % i == 0) {
output = 1;
break;
}
}
if(output == 0)
{
sleep(1);
}
return output;
}
void thread(myTest * pMyTest) {
printf("Begin threadID=%u run!\n", pMyTest->threadID);
int input, output;
int threadID = pMyTest->threadID;
int threadNum = pMyTest->threadNum;
int dataNum = pMyTest->dataNum;
int split = dataNum / threadNum;
int firstIndex = split * threadID;
int lastIndex = firstIndex + split;
if(lastIndex > dataNum)
lastIndex = dataNum;
while(firstIndex < lastIndex) {
input = pMyTest->input[firstIndex];
output = calculate(input);
printf("index=%3u, input=%8u, output=%2u, threadID=%2u\n", firstIndex, input, output, threadID);
pMyTest->output[firstIndex] = output;
firstIndex++;
}
pthread_exit(NULL);
}
int main(void) {
int i, ret;
int threadNum = 2;
myTest * pMyTest = (myTest *)malloc(sizeof(myTest));
pMyTest->dataNum = 100;
pMyTest->input = (int *)malloc(sizeof(int)*pMyTest->dataNum);
pMyTest->output = (int *)malloc(sizeof(int)*pMyTest->dataNum);
for(i=0; i<pMyTest->dataNum;++i) {
if(i % 4 == 0)
pMyTest->input[i] = (1 << (i%30)) + 1;
else
pMyTest->input[i] = (7 << (i%16)) + 1;
}
pMyTest->index = (int *)calloc(1, sizeof(int));
pMyTest->threadNum = threadNum;
myTest * inMyTest = (myTest *)malloc(sizeof(myTest)*threadNum);
for(i=0; i<threadNum; ++i) {
memcpy(inMyTest+i, pMyTest, sizeof(myTest));
(inMyTest+i)->threadID = i;
}
pthread_t * tid = (pthread_t*)malloc(sizeof(pthread_t)*threadNum);
printf("Begin create pthread.\n");
for(i=0; i<threadNum; ++i) {
ret = pthread_create(tid+i, NULL, (void *)thread, (myTest *)(inMyTest+i));
if(ret != 0) {
printf("Create pthread error.\n");
return 0;
}
}
for(i=0; i<threadNum; i++)
pthread_join(tid[i], NULL);
free(tid);
free(inMyTest);
free(pMyTest->input);
free(pMyTest->output);
free(pMyTest->index);
free(pMyTest);
return 0;
}
與上篇文章的代碼作比較,不同的地方主要在於thread函數中。在這個例子中所需要判斷是素數還是合數的數有100個,如果使用動態任務劃分,則只有打印出結果我們才能知道哪個線程操作了整型數組中的哪個數。而使用靜態任務劃分的這個程序規定了線程0處理的下標為0-49,線程1處理的下標為50-99。這就是動態任務劃分和靜態任務劃分的區別。
它們有各自的優缺點。
動態任務劃分——
優點:任務結束時間均等
缺點:需要上鎖和解鎖,有時需要頻繁等待
靜態任務劃分——
優點:任務劃分簡單,線程之間不需要通信
缺點:有時任務完成時間差距較大。