简介一般好的软件程序是不应该占用太多CPU时间和内存空间的,一般在自己的学习过程中,我们常常忽略这一点,虽然功能实现没有问题,但是程序占用太多CPU时间,这在实际开发中是不允许的,一个好的程序员也应该注意这个问题。本文就CPU使用率问题做一些简单介绍,为开发稳定健壮的程序提供参考。

前言

一般好的软件程序是不应该占用太多CPU时间和内存空间的,一般在自己的学习过程中,我们常常忽略这一点,虽然功能实现没有问题,但是程序占用太多CPU时间,这在实际开发中是不允许的,一个好的程序员也应该注意这个问题。本文就CPU使用率问题做一些简单介绍,为开发稳定健壮的程序提供参考。

简单例子

#include <iostream>
using namespace std;

int _tmain(int argc, _TCHAR* argv[])
{
	while (1)
	{

	}

	system("pause");
	return 0;
}

在任务管理器中可以看到该程序的CPU使用率:

程序优化,C++CPU使用

本次程序在双核Windows 64位系统下测试,也就是说 该程序占用了一半的CPU 。这个很容易理解,while循轮询CPU时间太快,CPU需要不断响应,造成很高的CPU使用率。很多时候我们想到在while循环中让程序休息一下,代码如下:

#include <Windows.h>
#include <iostream>
using namespace std;

int _tmain(int argc, _TCHAR* argv[])
{
	while (1)
	{
		Sleep(1);
	}

	system("pause");
	return 0;
}

在任务管理器中可以看到该程序的CPU使用率:

程序优化,C++CPU使用

这样可以看到让程序休息一会,占用CPU的使用时间就大为减少,这样对于一些实时性要求不是很高的程序,这样处理是可以的。

单线程测试

前面的例子有点简单,在实际应用中,这个问题多体现在多线程中。先写个单线程测试:

 #include <windows.h>
#include <process.h>
#include <iostream>
using namespace std;

unsigned __stdcall ThreadFunc(void* pArguments)
{
	// 执行线程任务
	while (1)
	{
		cout << "thread is running..." << endl;
	}

	// 中止线程
	_endthreadex(0);
	return 0;
}

int _tmain(int argc, _TCHAR* argv[])
{
	HANDLE hThread;

	// 启动线程
	hThread = (HANDLE)_beginthreadex(NULL, 0, &ThreadFunc, NULL, 0, NULL);

	// 等待线程完成
	WaitForSingleObject(hThread, INFINITE);

	// 关闭线程句柄
	CloseHandle(hThread);

	system("pause");
	return 0;
}

在任务管理器中可以看到该程序的CPU使用率:

程序优化,C++CPU使用

如果把下面语句注释掉:

unsigned __stdcall ThreadFunc(void* pArguments)
{
	// 执行线程任务
	while (1)
	{
		//cout << "thread is running..." << endl;
	}

	// 中止线程
	_endthreadex(0);
	return 0;
}

会发现CPU使用率又达到50%,综合前面,可以看出, 让线程输出或者Sleep可以大大减少占用CPU时间,其中Sleep效果更优

多线程测试

#include <windows.h>
#include <process.h>
#include <iostream>
using namespace std;

unsigned __stdcall ThreadFunc(void* pArguments)
{
	// 执行线程任务
	while (1)
	{
	}

	// 中止线程
	_endthreadex(0);
	return 0;
}

int _tmain(int argc, _TCHAR* argv[])
{
	const int nThreadNum = 20;
	HANDLE hThread[nThreadNum];

	// 启动线程
	for (int i = 0; i < nThreadNum; ++i)
	{
		hThread[i] = (HANDLE)_beginthreadex(NULL, 0, &ThreadFunc, NULL, 0, NULL);
	}
	
	// 等待线程完成
	for (int i = 0; i < nThreadNum; ++i)
	{
		WaitForSingleObject(hThread[i], INFINITE);
	}

	// 关闭线程句柄
	for (int i = 0; i < nThreadNum; ++i)
	{
		CloseHandle(hThread[i]);
	}

	system("pause");
	return 0;
}

在任务管理器中可以看到该程序的CPU使用率:

程序优化,C++CPU使用

可见,这几乎占据了CPU的所有时间,系统卡住了。可见,在多线程中,while循环的使用更需要谨慎。

同样我们让每个线程都输出,结果得到优化:

 cout << "thread is running..." << endl;

程序优化,C++CPU使用

同样我们让每个线程都睡眠1ms,结果更化:

程序优化,C++CPU使用

至此,我们可以总结一下,对于实时性要求不是很高的程序,我们在使用while循环的时候要让执行体睡眠或者输出都可以大大减少程序占用CPU时间,但睡眠效果更优,但许多时候不需要输出,所以睡眠是一种不错的选择。

但是睡眠也要注意:对于实时工作线程,睡眠1ms为佳;对于主线程(通常为控制台界面线程),为了保持运行,一般在main函数中加入while循环,在while里面sleep多久虽然理论上是一样的,但为了让每个sleep运行一点,个人习惯使用Sleep(10000).

更多为你推荐