并行计算之实验三

小作业1

任务:统计输出素数的个数

思路:

(1)添加一个全局变量:记录素数的个数

(2)在素数统计函数中当判断输入的数据为素数时,num变量加1,在对num进行操作时要先加锁,当数据操作完之后进行解锁。

(3)在main()函数中当所有的线程工作结束时,输出num变量。

 出现的问题:在不加锁的情况下最后统计的素数个数会出现重复计算的错误!


小作业2

任务:每次处理多个元素(注意如果剩余元素不足十个,要特殊处理)

前期准备:在源程序中每个线程获取一个元素判定是否为素数

思路:

(1)首先本程序是创建两个线程进行素数合数判断,当两个线程函数进行工作时它们的索引起始位置分别从010开始,注:那个线程运行先抢占到CPU资源就从起始位置0开始,另一个线程则从起始位置10开始

(2)然后从内存中连续读取10个数据,依次进行素数的判断,采用局部变量index++,利用for循环,逻辑详见代码。

(3)每当线程处理完10个数据之后,采用线程锁,更新起始指针的位置,在原来的位置上加10

(4)当最后数据剩余不到10个时,进行特殊处理,剩余几个数据就进行几次处理;(实现逻辑详见代码)

(5)实现效果:源程序中线程每处理完一个数据,就采用线程锁对指针的位置进行修改,线程之间进行多达100次的交互,相互等待的时间过长,这样会浪费大量的cpu资源;这样改进后,在对100个数据进行素数判断时,每完成10个数据处理就进行线程锁交互,大大减少了两个线程间相互影响的次数,从而提高了资源的使用效率。

小作业2核心代码:

/*
 ============================================================================
 Name        : Mytest.c
 Author      : passionYang
 Version     :1.0
 Copyright   : Your copyright notice
 Description : Hello World in C, Ansi-style
 ============================================================================
 */
/* */
#include <stdio.h>
#include <pthread.h>

int num = 0; //声明全局

typedef struct myTestType {
	int threadID;
	int threadNum;
	int dataNum;

	int *inPut;
	int *outPut;
	int *index;
	pthread_mutex_t *pMutIndex;
} myTest;

int calculate(int inPut) {
	int i;
	int outPut = 0; //素数:0,和数:1
	for (i = 2; i < inPut / 2; i++) {
		if (inPut % i == 0) {
			outPut = 1;
			break;
		}
	}
	if (outPut == 0) {
		/* count num*/
		sleep(1);
	}

	return outPut;
}
void thread(myTest* pMyTest) {
	printf("Begin threadID = %u Run!\n", pMyTest->threadID);
	int i, n;
	int index, inPut, outPut;
	int threadID = pMyTest->threadID;
	int dataNum = pMyTest->dataNum;
	pthread_mutex_lock(pMyTest->pMutIndex);
	index = pMyTest->index[0];
	pMyTest->index[0] += 10;//第二个运行的线程起始位置从10开始
	pthread_mutex_unlock(pMyTest->pMutIndex);
	while (index < dataNum) {
		//每次处理10个元素
		n = dataNum - index ;	//查看剩余数据的个数
		if (n < 10)	//当剩余的数据个数少于10个
		{
			printf("不足10个数据 = %u Run!\n", n);
			for (i = 0; i < n; i++) {	//剩余几个数据就进行几次处理

				inPut = pMyTest->inPut[index];
				outPut = calculate(inPut);
				if (outPut == 0) {
					/* count num*/
					pthread_mutex_lock(pMyTest->pMutIndex);	//加锁
					num++;	//统计素数的个数
					pthread_mutex_unlock(pMyTest->pMutIndex);	//开锁
				}
				printf(
						"index=%3u,    inPut=%8u,    outPut=%2u, threadID=%2u \n",
						index, inPut, outPut, threadID);
				pMyTest->outPut[index] = outPut;
				index++;
			}
			break;//处理完最后的数据要跳出循环
		}
		for (i = 0; i < 10; i++) {	//每次处理10个数据

			inPut = pMyTest->inPut[index];
			outPut = calculate(inPut);
			if (outPut == 0) {
				/* count num*/
				pthread_mutex_lock(pMyTest->pMutIndex);	//加锁
				num++;	//统计素数的个数
				pthread_mutex_unlock(pMyTest->pMutIndex);	//开锁
			}
			printf("index=%3u,    inPut=%8u,    outPut=%2u, threadID=%2u \n",
					index, inPut, outPut, threadID);
			pMyTest->outPut[index] = outPut;
			index++;
		}

		pthread_mutex_lock(pMyTest->pMutIndex);
		index = pMyTest->index[0];
		for (i = 0; i < 10; i++) {
			pMyTest->index[0]++;	//指针的位置移动10
		}
		pthread_mutex_unlock(pMyTest->pMutIndex);
	}
	pthread_exit(NULL);
}
int main(void) {
	int i, ret;
	int threadNum = 2;
	myTest* pMyTest = (myTest*) malloc(sizeof(myTest));
	pMyTest->dataNum = 109;
	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->pMutIndex = (pthread_mutex_t*) malloc(sizeof(pthread_mutex_t));
	pthread_mutex_init(pMyTest->pMutIndex, NULL);

	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);
	/*print num*/
	printf("素数个数:%d\n", num);

	free(tid);
	free(inMyTest);
	pthread_mutex_destroy(pMyTest->pMutIndex);
	free(pMyTest->pMutIndex);
	free(pMyTest->inPut);
	free(pMyTest->outPut);
	free(pMyTest->index);
	free(pMyTest);
	return (0);

}


  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值