5、gdb学习之多线程调试

版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接: https://blog.csdn.net/qq_29983883/article/details/102649896

首先贴上本节的代码

//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就学到这个里,等到以后还有其他的,再更新了,

猜你喜欢

转载自blog.csdn.net/qq_29983883/article/details/102649896
今日推荐