项目概述:
要求使用c++语言,利用多线程并发来测试磁盘的读写速度。并按照一定的时率定期显示读写速度(磁盘的读写速度受到温度等各项因素影响会略有偏差)。
项目构思:
如何能知道磁盘的读写速度呢,最先想到的应是向磁盘写入一定大小的文件,并通过文件大小除以间隔时间,就能实时的监测到间隔段内的读写速度。而多线程并发测试就让每一个线程都执行写文件操作,这样就可以达到多线程并发上传。
项目实践:
问题点1:如何来知晓当前实际的上传大小呢?
- 首先我们可以控制每次向文件中写入字节数的量,然后通过循环执行,就可以知道当前已向文件中写入的字节大小。
- 其次,我们设置一个全局变量,用来存储所有线程当前时刻的上传大小。
- 最后让每一个线程互斥的去修改全局变量,以获的所有线程当前的上传大小。
//定义全局变量文件大小
double fileSize = 0.0;
//定义互斥量
mutex m_mutex;
// 定义文件
fstream file;
string str = "C:\\Users\\LENOVO\\Desktop\\test\\text.txt";
//线程执行函数
void read_disk_speed(int num){
for(int i = 0;i < 10000000;i++){
m_mutex.lock();
file.write ((char *) &num, sizeof( num ) );
fileSize += 0.00390625; //int占4B,将它换算成KB
m_mutex.unlock();
}
break;
}
问题点2:如何实时显示磁盘读写速率呢?
- 使用休眠函数,将它放置在循环函数当中,每隔一定时间去执行一次速率计算函数
- 循环函数的出口判断,应根据线程执行的总次数判断出所有数据传输完毕后的总大小
//实时速度输出函数
double printSpeed(double time) {
double speed = (fileSize/1024)/time;
cout << "当前上传大小为:" << fileSize << " KB" << endl;
cout << "当前上传时间为:" << time << endl;
cout << "当前上传速度为:" << speed << "Mb/S" << endl;
cout << "*************************************************************" << endl;
return speed;
}
int main(){
// 实施测试函数
double time = 0.5;
double allSpeed = 0;
while (fileSize < num*10000000*0.00390625) {
Sleep(500);
allSpeed += printSpeed(time);
time += 0.5;
}
}
我们每半秒执行一次测速,根据所有线程上传的总字节数,除以时间,再换算单位,就可以得到实时的磁盘读写速度啦。
最后,我们根据每次间隔记录的速度求以平均速度,并向用户进行显示。
cout << endl << "传输已完成。" << endl;
cout << "共传输字节:" << fileSize/1024 << " MB" << endl;
cout << "平均上传速度为:" << allSpeed/((time-0.5)*2) << "Mb/S" << endl;
为了让项目变得更加智能化,我们可以进行设置,由用户来选择并发执行的线程数,并且能够设置文件的传输形式(以二进制形式传输/以字符形式传输),我们可以对代码进行如下修改。
#include<iostream>
#include<thread>
#include<fstream>
#include<vector>
#include<bitset>
#include <time.h>
#include<mutex>
#include<windows.h>
using namespace std;
//定义全局变量时钟
clock_t start;
clock_t finish;
//定义全局变量文件大小
double fileSize = 0.0;
//定义互斥量
mutex m_mutex;
//定义单次传输数据大小
double size;
// 定义文件
fstream file;
string str = "C:\\Users\\LENOVO\\Desktop\\test\\text2.txt";
//线程执行函数
void read_disk_speed(int num,int mode){
switch (mode) {
case 1:
for(int i = 0;i < 10000000;i++){
m_mutex.lock();
file.write ((char *) &num, sizeof( num ) );
fileSize += size;
m_mutex.unlock();
}
break;
case 2:
for(int i = 0;i < 10000000;i++){
m_mutex.lock();
file <<'1';
fileSize += size;
m_mutex.unlock();
}
break;
}
}
//创建线程函数
thread creatThread(int num,int mode){
thread a(read_disk_speed,num,mode);
return a;
}
//实时速度输出函数
double printSpeed(double time) {
double speed = (fileSize/1024)/time;
cout << "当前上传大小为:" << fileSize << " KB" << endl;
cout << "当前上传时间为:" << time << endl;
cout << "当前上传速度为:" << speed << "Mb/S" << endl;
cout << "*************************************************************" << endl;
return speed;
}
int main(){
//线程数量
int num;
//文件写入模式
int mode;
cout << "请输入将要执行文件上传的线程数量:";
cin >> num;
system("cls");
cout << "*************************" << endl;
cout << " 1、以二进制模式写入: " << endl;
cout << " 2、以字符模式写入: " << endl;
cout << "*************************" << endl;
cout << "请选择文件写入模式:";
cin >> mode;
if(mode == 1)
size = 0.00390625;
else
size = 0.0029296875;
//打开文件
file.open(str,ios::out|ios::binary);
//定义线程容器
vector<thread> vTh;
//循环创建10个线程
for (auto i = 0; i < num; i++) {
vTh.push_back(creatThread(i,mode));
}
// 实施测试函数
double time = 0.5;
double allSpeed = 0;
while (fileSize < num*10000000*size) {
Sleep(500);
allSpeed += printSpeed(time);
time += 0.5;
}
//将10个线程加入主线程中进行阻塞
for (auto vit = vTh.begin(); vit != vTh.end(); vit++) {
if (vit->joinable()) {
vit->join();
}
}
//关闭文件
if(file.is_open())
file.close();
cout << endl << "传输已完成。" << endl;
cout << "共传输字节:" << fileSize/1024 << " MB" << endl;
cout << "线程数:" << num << endl;
cout << "平均上传速度为:" << allSpeed/((time-0.5)*2) << "Mb/S" << endl;
}
项目结果展示