程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> C語言 >> C++ >> C++入門知識 >> 多線程(三):動態任務劃分&靜態任務劃分

多線程(三):動態任務劃分&靜態任務劃分

編輯:C++入門知識

首先這是老師給出的定義——

靜態任務劃分:問題劃分成相對獨立的與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。這就是動態任務劃分和靜態任務劃分的區別。

它們有各自的優缺點。

動態任務劃分——

優點:任務結束時間均等

缺點:需要上鎖和解鎖,有時需要頻繁等待

靜態任務劃分——

優點:任務劃分簡單,線程之間不需要通信

缺點:有時任務完成時間差距較大。

 

  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved