[总结] C++ 知识点 《四》多线程相关

简介: [总结] C++ 知识点 《四》多线程相关

前言

以一个面试题为例子:

  1. 读取data.txt文件内容

  2. 使用多线程处理
  3. 使用宏定义线程数量

第一版实现:(面试时写得答案是这个类似)

#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;
}

面试的大佬 给提了几个建议:

  1. 尽量不要用锁 (用户态转为内核态需要一些开销)
  2. 尽量不要裸指针,裸指针容易忘记销毁 异常捕获会被上层捕获 内存泄漏。

同时申明一点智能指针具有传递性,函数的形参也需要是智能指针。

  1. 尽量使用c++读取文件,虽然c原生比c++流 速度快。
  2. 尽量不要使用全局变量
  3. 主线程也要用上,这算小技巧
  4. 线程算法能优化,可以使用Google的map-reduces算法,类似根据线程数量把数据进行分段处理。

当时在ubuntu上编程的,很懵逼,线程库用不了,需要qt pro文件 添加 LIBS += pthread.lib


相关文章
|
1月前
|
存储 前端开发 Java
【C++ 多线程 】C++并发编程:精细控制数据打印顺序的策略
【C++ 多线程 】C++并发编程:精细控制数据打印顺序的策略
45 1
|
1月前
|
数据可视化 关系型数据库 编译器
【C/C++ 单线程性能分析工具 Gprof】 GNU的C/C++ 性能分析工具 Gprof 使用全面指南
【C/C++ 单线程性能分析工具 Gprof】 GNU的C/C++ 性能分析工具 Gprof 使用全面指南
115 2
|
1月前
|
存储 算法 Java
【C/C++ 线程池设计思路】 深入探索线程池设计:任务历史记录的高效管理策略
【C/C++ 线程池设计思路】 深入探索线程池设计:任务历史记录的高效管理策略
83 0
|
1月前
|
消息中间件 Linux 调度
【Linux 进程/线程状态 】深入理解Linux C++中的进程/线程状态:阻塞,休眠,僵死
【Linux 进程/线程状态 】深入理解Linux C++中的进程/线程状态:阻塞,休眠,僵死
70 0
|
22天前
|
Java
java线程知识点总结
Java线程核心概念:线程是程序执行流,一个进程可有多个线程。创建线程通过继承Thread或实现Runnable接口。线程状态包括新建、就绪、运行、阻塞、等待、超时等待和终止。同步用synchronized或Lock防止数据不一致,避免死锁。线程间通过共享变量、wait/notify通信。线程池(如ThreadPoolExecutor、ScheduledThreadPoolExecutor)优化性能和资源管理。
17 6
|
1月前
|
安全 Java 调度
【C/C++ 线程池设计思路 】设计与实现支持优先级任务的C++线程池 简要介绍
【C/C++ 线程池设计思路 】设计与实现支持优先级任务的C++线程池 简要介绍
45 2
|
1月前
|
Linux API C++
【C++ 线程包裹类设计】跨平台C++线程包装类:属性设置与平台差异的全面探讨
【C++ 线程包裹类设计】跨平台C++线程包装类:属性设置与平台差异的全面探讨
56 2
|
1月前
|
设计模式 安全 C++
【C++ const 函数 的使用】C++ 中 const 成员函数与线程安全性:原理、案例与最佳实践
【C++ const 函数 的使用】C++ 中 const 成员函数与线程安全性:原理、案例与最佳实践
83 2
|
1月前
|
存储 算法 搜索推荐
【C++ 数据结构与算法 一站式备考指南】一文掌握 数据结构与算法课程 知识点(二)
【C++ 数据结构与算法 一站式备考指南】一文掌握 数据结构与算法课程 知识点
94 2
|
1月前
|
存储 算法 C++
【C++ 数据结构与算法 一站式备考指南】一文掌握 数据结构与算法课程 知识点(一)
【C++ 数据结构与算法 一站式备考指南】一文掌握 数据结构与算法课程 知识点
51 2