windows多线程 1

 

        关于多线程我总觉得是个比较难的东西,难在几点,比如线程的同步互斥等,还有实际编写代码时遇到的线程的调试问题,这些都是造成多线程比较难的原因,不过没有办法,还是需要面对,学习顺便做个记录和分析:

        首先是源代码,如下(不同的问题需要自己修改源代码),程序最初的目的是加快x的运算速度,所以最初是采用的两个线程的形式,后来经过改进和分析即产生如下的源码原型。只作为分析用。

#define WIN32_LEAN_AND_MEAN

#include <stdio.h>
#include <stdlib.h>
#include <windows.h>

__int64 x=0;
__int64 y=0;
__int64 z=0;
__int64 q=0;

#define MAX 10000000000

DWORD WINAPI ThreadFunc1(LPVOID);
DWORD WINAPI ThreadFunc2(LPVOID);
DWORD WINAPI ThreadFunc3(LPVOID);
DWORD WINAPI ThreadFunc4(LPVOID);
//目地是并行计算x的大小,让他很快的到最大的值,这样的话没有进行并行计算。


int main()
{
	HANDLE hThrd[2];
	DWORD threadId[2];
//	HANDLE hThrd[4];
//	DWORD threadId[4];
	DWORD start_time = GetTickCount();			//获取系统时钟
	hThrd[0] = CreateThread(NULL,
							0,
							ThreadFunc1,
							(LPVOID)0,
							0,
							&threadId[0]);
/*	hThrd[1] = CreateThread(NULL,
							0,
							ThreadFunc2,
							(LPVOID)0,
							0,
							&threadId[1]);
*/							
/*	hThrd[2] = CreateThread(NULL,
		0,
		ThreadFunc3,
		(LPVOID)0,
		0,
		&threadId[2]);
	hThrd[3] = CreateThread(NULL,
		0,
		ThreadFunc4,
		(LPVOID)0,
		0,
		&threadId[3]);
*/		
//	WaitForMultipleObjects(2,hThrd,TRUE,INFINITE);
//	Sleep(1000);
//	WaitForMultipleObjects(4,hThrd,TRUE,INFINITE);
	WaitForSingleObject(hThrd[0],INFINITE);
	CloseHandle(hThrd[0]);
	CloseHandle(hThrd[1]);
//	x= x+y;
//	x= x+y+z+q;
	DWORD end_time = GetTickCount();

	printf("time :%d\n",end_time-start_time);
	printf("x: %I64d\n",x);
	return EXIT_SUCCESS;
}

DWORD WINAPI ThreadFunc1(LPVOID)
{
	while(x<MAX)
	{
		x++;
//	 	printf("thread1: %d\n",x);
//		Sleep(10);
	}
	return 0;
} 

DWORD WINAPI ThreadFunc2(LPVOID)
{
	while(y<MAX/2)
//	while(x<10000000)
	{
		y++;
//		x++;
//		printf("thread2: %d\n",x);
//		Sleep(10);
	}
	return 0;
}

DWORD WINAPI ThreadFunc3(LPVOID)
{
//	while(x<10000000)
	while(z<MAX/4)
	{
		z++;
//		x++;
//		printf("thread3: %d\n",x);
//		Sleep(10);
	}
	return 0;
} 

DWORD WINAPI ThreadFunc4(LPVOID)
{
//	while(x<10000000)
	while(q<MAX/4)
	{
		q++;
//		x++;
//		printf("thread4: %d\n",x);
//		Sleep(10);
	}
	return 0;
}

下面针对不同的问题产生的不同结结果,首先是采用多线程直接对x自加,单个线程的情况(time :31 x: 10000000),然后是两个线程(time :16 x: 10000000),(time :31 x: 10000000)每次运行的时间可能不一样,并且差别较大,更多的时候时间为31,32左右,然后是四个线程,四个线程时间反而比两个线程运行的时间长一些(time :47 x: 10000000),有时是(time :31 x: 10000000),也不是稳定的,关于执行时间为什么会长一些后面做解释,这里为什么两个线程,四个线程基本上没有加快速度,直接对x进行自加的操作,真正意义上并没有做到并行计算x。并行计算需要将x进行分割,然后启用多个线程同时运行,至于多少个线程就需要看实际的情况,

将数据分割后,采用两个线程时,结果为(time :16  x: 10000000),时间一般是15,16趋于稳定,四个线程时间是否会编程4左后呢?,我猜想是的,但是结果确不是的,和两个线程的情况基本相同,这里有一点不懂,为什么时间基本上没有缩短,(我猜想可能是我的电脑为双核的原因)其实是真的不明白!!!

于是我把数据变大到10000000000,单个线程的结果为(time :31699   x: 10000000000),两个线程的时间为(time :24570   x: 10000000000),四个线程的时间为

(time :23759 x: 10000000000),这里从1个到2个到4个线程基本上时间没有很明显的呈现两倍的趋势,主要还有一个原因就是,这几个线程都属于同一个进程,他们共享所有的内存,当线程同时运行时,会发生context switch(我称为设备文转换),而每次的context switch都会话费一点时间,也就是说"两个线程同时计算x比一个线程计算x两次的时间要长一些"当数据比较小时,转换的次数相对比较少,可以忽略,但是当数据比较大,就不能忽略,也就出现了后面的结果的时间分布情况。

总结:1 真正的数据并发需要对数据进行分布式的切割计算

          2 当数据比较大时,用多少个进程,需要考虑context switch



评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值