通常多线程编程任务分发包括:分块法、交叉分配法、池类分配法。池类分配法能够最有效地避免计算任务分配不均匀的情况。
线程池思想包括:
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);
}