通常多線程編程任務分發包括:分塊法、交叉分配法、池類分配法。池類分配法能夠最有效地避免計算任務分配不均勻的情況。
線程池思想包括:
1 main線程負責分發任務
2 全局變量num:num>0時有待計算任務,num=0時無算任務需要上游分發,num=-1時無計算任務所有線程退出
3 互斥量:獲取資源前一定先上鎖,臨界區內的跳轉語句,跳轉到臨界區外一定要及時釋放鎖資源
篩質數代碼如下:
#include<stdio.h>
#include<stdlib.h>
#include <unistd.h>
#include <pthread.h>
#include <string.h>
#define LEFT 30000000
#define RIGHT 30001911
#define THRUNM 3
//全局變量負責記錄資源
static int num=0;
//互斥量
static pthread_mutex_t mut = PTHREAD_MUTEX_INITIALIZER;
void *func(void *p)
{
int i,mark,j;
int number = (int) p;
while(1)
{
pthread_mutex_lock(&mut);
while(num == 0)
{
pthread_mutex_unlock(&mut);
sched_yield(); //超級短的sleep
pthread_mutex_lock(&mut);
}
if(num == -1)
{
pthread_mutex_unlock(&mut);
break;
}
i = num;
num = 0;
pthread_mutex_unlock(&mut);
mark =1;
for(j=2; j<i/2;j++)
{
if(i%j == 0)
{
mark =0;
break;
}
}
if(mark) {
printf("%d號線程計算出來:%d is primer\n", number,i);
}
}
pthread_exit(NULL);
}
int main(int argc, char **argv)
{
int i,err;
pthread_t tid[THRUNM];
for(i=0;i<THRUNM;i++)
{
err = pthread_create(tid+i, NULL, func, (void *)i); //i一個地址被THRUNM個指針指向
if(err)
{
fprintf(stdout,"pthread_create %s\n", strerror(err));
exit(1);
}
}
//main線程負責下發任務
for(i=LEFT;i<=RIGHT;i++)
{
pthread_mutex_lock(&mut);
//任務還在未被搶走
while(num != 0)
{
pthread_mutex_unlock(&mut);
sched_yield(); //超級短的sleep,不會造成進程調度顛簸
pthread_mutex_lock(&mut);
}
num = i;
pthread_mutex_unlock(&mut);
}
sched_yield();
pthread_mutex_lock(&mut);
//退出線程
num = -1;
pthread_mutex_unlock(&mut);
for(i=0;i<THRUNM;i++)
{
pthread_join(tid[i], NULL);
}
pthread_mutex_destroy(&mut);
exit(0);
}