首先贴上本节的代码
//thread.c
#include <stdio.h>
#include <stdlib.h>
#include <pthread.h>
#define MAX_N 1000000
#define MAX_THREADS 100
int nthreads,
n,
prime[MAX_N+1],
nextbase;
int work[MAX_THREADS];
pthread_mutex_t nextbaselock = PTHREAD_MUTEX_INITIALIZER;
pthread_t id[MAX_THREADS];
void crossout(int k){
int i;
for(i = k;i*k <= n;i++){
prime[i*k] = 0;
}
}
void * worker(int tn){
int lim,base;
do{
pthread_mutex_lock(&nextbaselock);
base = nextbase+=2;
//pthread_mutex_unlock(&nextbaselock);
if(base*base <=lim){
work[tn]++;
if(prime[base])
crossout(base);
}else
return 0;
}while(1);
}
int main(int argc,char **argv){
int nprimes,
totwork,
i;
void *p;
n = atoi(argv[1]);
nthreads = atoi(argv[2]);
for( i = 2;i <= n;i++)
prime[i]= 1;
crossout(2);
nextbase =1;
for( i= 0;i < nthreads;i++)
pthread_create(&id[i],NULL,(void*)worker,(void*)i);
totwork = 0;
for(i =0;i < nthreads;i++){
pthread_join(id[i],&p);
printf("%d values of base done\n",work[i]);
totwork +=work[i];
}
printf("%d total values of base done\n",totwork);
nprimes = 0;
for(i = 2;i <= n;i++)
if(prime[i]) nprimes++;
printf("the number of primes found was %d\n",nprimes);
}
上面是求一个范围的素数的多线程编程,编译需要使用gcc -g thread.c -lpthread
,添加thread的链接库,否则编程报错
编译后我们进入gdb,通过命令r 100 3
后,发现程序停顿了,如图
上面图片可以看出有一个线程已经退出,还有三个线程,总的是四个线程,分别是一个主线程和三个计算线程。退出的是那个计算线程,但是为什么程序会卡顿呢,通过ctr+c将程序挂起,查看线程情况
星号表示当前运行的线程。使用backtrace
查看当前线程的调用栈情况,如图
发现当前线程的调用栈只用两个函数,同时也知道这个主线程,因为底层调用函数是main函数。
使用thread id
来切换线程3,查看调用栈情况
发现frame 3和frame 2是获取锁而被挂起,这个明白了,线程3是由于没有获得锁而一直被挂起,同样线程4也是这个情况,这是发现最大的祸首是线程2在gg之前没有释放锁引起的,就是这里
我们把注释删了重新编译一遍。功德圆满
目前gdb就学到这个里,等到以后还有其他的,再更新了,