文章目录
前言
以一个面试题为例子:
-
读取data.txt文件内容
-
使用多线程处理
-
使用宏定义线程数量
第一版实现:(面试时写得答案是这个类似)
#include <stdio.h>
#include <stdlib.h>
#include <vector>
#include <iostream>
#include <memory>
#include <thread>
#include <mutex>
#define MAX_SIZE 200*1024
#define MAX_THREAD_COUNT 10
int main() {
FILE* pFile = fopen("D:\\workspace\\vs2015\\Project1\\Debug\\data.txt","rb");
if (!pFile) {
printf("file open error \n");
return -1;
}
char szBuff[MAX_SIZE] = { 0 };
int i = 0;
while (!feof(pFile)) {
fread(&szBuff[i * 1024], 1, 1024, pFile);
i++;
}
fclose(pFile);
char szDoubleValue[8] = {0};
int nDoubleValueIndex = 0;
std::vector<double> vectDoubleList;
for (size_t i = 0; i < strlen(szBuff); i++)
{
if (szBuff[i] == '\r') {
float fValue = atof(szDoubleValue);
vectDoubleList.push_back(fValue);
//printf("%f\n", fValue);
continue;
}
if (szBuff[i] == '\n') {
nDoubleValueIndex = 0;
memset(szDoubleValue, 0, 8);
continue;
}
szDoubleValue[nDoubleValueIndex] = szBuff[i];
nDoubleValueIndex++;
}
if (vectDoubleList.size() <= 0) {
printf("vectDoubleList empty \n");
return -1;
}
std::unique_ptr<std::thread> thThreadPtrList[MAX_THREAD_COUNT - 1];
volatile int nHasProIndex = 0;
double dTotalValue = 0;
int size = vectDoubleList.size();
std::mutex lock;
long lStartTime = clock();
for (size_t i = 0; i < MAX_THREAD_COUNT - 1; i++)
{
thThreadPtrList[i] = std::unique_ptr<std::thread>(
new std::thread([&]() {
while(1)
{
std::lock_guard<std::mutex> locker(lock);
if (nHasProIndex != size) {
dTotalValue += vectDoubleList[nHasProIndex];
nHasProIndex++;
}
else {
break;
}
}
})
);
}
while (1)
{
std::lock_guard<std::mutex> locker(lock);
if (nHasProIndex != size) {
dTotalValue += vectDoubleList[nHasProIndex];
nHasProIndex++;
}
else {
break;
}
}
long lEndTime = clock();
double dAvarageValue = dTotalValue / vectDoubleList.size();
printf("Total Count:%d \nMedium Value:%f \nAvarage Value:%f \n", vectDoubleList.size(),vectDoubleList[vectDoubleList.size()/2], dAvarageValue);
printf("Total Time:%d \n", lEndTime - lStartTime);
for (size_t i = 0; i < MAX_THREAD_COUNT -1; i++)
{
thThreadPtrList[i]->join();
}
system("pause");
return 0;
}
面试的大佬 给提了几个建议:
- 尽量不要用锁 (用户态转为内核态需要一些开销)
- 尽量不要裸指针,裸指针容易忘记销毁 异常捕获会被上层捕获 内存泄漏。
同时申明一点智能指针具有传递性,函数的形参也需要是智能指针。
- 尽量使用c++读取文件,虽然c原生比c++流 速度快。
- 尽量不要使用全局变量
- 主线程也要用上,这算小技巧
- 线程算法能优化,可以使用Google的map-reduces算法,类似根据线程数量把数据进行分段处理。
当时在ubuntu上编程的,很懵逼,线程库用不了,需要qt pro文件 添加 LIBS += pthread.lib