C++ MYSQL 多线程并发查询处理数据

2023-11-18

1. ThreadPool.hpp

#pragma once

#ifndef THREAD_POOL_H
#define THREAD_POOL_H

#include <vector>
#include <queue>
#include <thread>
#include <atomic>
#include <condition_variable>
#include <future>
#include <functional>
#include <stdexcept>

namespace haifan
{
#define  MAX_THREAD_NUM 256

class ThreadPool
{
    using Task = std::function<void()>;
    // 线程池
    std::vector<std::thread> pool;
    // 任务队列
    std::queue<Task> tasks;
    // 同步
    std::mutex m_lock;
    // 条件阻塞
    std::condition_variable cv_task;
    // 是否关闭提交
    std::atomic<bool> stoped;
    //空闲线程数量
    std::atomic<int>  idlThrNum;

public:
    inline ThreadPool(unsigned short size = 4) :stoped{ false }
    {
        idlThrNum = size < 1 ? 1 : size;
        for (size = 0; size < idlThrNum; ++size)
        {   //初始化线程数量
            pool.emplace_back(
                [this]
                { // 工作线程函数
                    while(!this->stoped)
                    {
                        std::function<void()> task;
                        {   // 获取一个待执行的 task
                            std::unique_lock<std::mutex> lock{ this->m_lock };// unique_lock 相比 lock_guard 的好处是:可以随时 unlock() 和 lock()
                            this->cv_task.wait(lock,
                                [this] {
                                    return this->stoped.load() || !this->tasks.empty();
                                }
                            ); // wait 直到有 task
                            if (this->stoped && this->tasks.empty())
                                return;
                            task = std::move(this->tasks.front()); // 取一个 task
                            this->tasks.pop();
                        }
                        idlThrNum--;
                        task();
                        idlThrNum++;
                    }
                }
            );
        }
    }
    inline ~ThreadPool()
    {
        stoped.store(true);
        cv_task.notify_all(); // 唤醒所有线程执行
        for (std::thread& thread : pool) {
            //thread.detach(); // 让线程“自生自灭”
            if(thread.joinable())
                thread.join(); // 等待任务结束, 前提:线程一定会执行完
        }
    }

public:
    // 提交一个任务
    // 调用.get()获取返回值会等待任务执行完,获取返回值
    // 有两种方法可以实现调用类成员,
    // 一种是使用   bind: .commit(std::bind(&Dog::sayHello, &dog));
    // 一种是用 mem_fn: .commit(std::mem_fn(&Dog::sayHello), &dog)
    template<class F, class... Args>
    auto push_task(F&& f, Args&&... args) ->std::future<decltype(f(args...))>
    {
        if (stoped.load())    // stop == true ??
            throw std::runtime_error("commit on ThreadPool is stopped.");

        using RetType = decltype(f(args...)); // typename std::result_of<F(Args...)>::type, 函数 f 的返回值类型
        auto task = std::make_shared<std::packaged_task<RetType()> >(
            std::bind(std::forward<F>(f), std::forward<Args>(args)...)
            );    // wtf !
        std::future<RetType> future = task->get_future();
        {    // 添加任务到队列
            std::lock_guard<std::mutex> lock{ m_lock };//对当前块的语句加锁  lock_guard 是 mutex 的 stack 封装类,构造的时候 lock(),析构的时候 unlock()
            tasks.emplace(
                [task]()
                { // push(Task{...})
                    (*task)();
                }
            );
        }
        cv_task.notify_one(); // 唤醒一个线程执行

        return future;
    }

    //空闲线程数量
    int idlCount() { return idlThrNum; }

};

}

#endif

2. main.cpp

#include "mysql_connection.h"
#include <string>
#include <iostream>
#include <sstream>

#include <cppconn/driver.h>
#include <cppconn/exception.h>
#include <cppconn/resultset.h>
#include <cppconn/statement.h>
#include "threadpool.hpp"
#include <math.h>

using namespace std;
using namespace haifan;


int read_dat_count() {
    int count = 0;
    try
    {
        sql::Driver *driver;
        sql::Connection *con;
        sql::Statement *stmt;
        sql::ResultSet *res;

        /* Create a connection */
        driver = get_driver_instance();
        con = driver->connect("tcp://10.0.0.31:3306", "root", "haifan123!@#");
        /* Connect to the MySQL test database */
        con->setSchema("hf_face_sys");

        stmt = con->createStatement();
        res = stmt->executeQuery("select count(*) from faces_bigdata;");
        while (res->next())
        {
            //cout << "\t... MySQL replies: ";
            /* Access column data by alias or column name */
            //cout << res->getString(1) << endl;
            count = res->getInt64(1);
        }
        std::cout << "this_thread id = " << std::this_thread::get_id() << std::endl;
        delete res;
        delete stmt;
        delete con;
    }
    catch (sql::SQLException &e)
    {
        cout << "# ERR: SQLException in " << __FILE__;
        cout << "(" << __FUNCTION__ << ") on line " << __LINE__ << endl;
        cout << "# ERR: " << e.what();
        cout << " (MySQL error code: " << e.getErrorCode();
        cout << ", SQLState: " << e.getSQLState() << " )" << endl;
    }

    return count;
}

int read_sql_dat(int start, int limit) {
    try
    {
        sql::Driver *driver;
        sql::Connection *con;
        sql::Statement *stmt;
        sql::ResultSet *res;

        /* Create a connection */
        driver = get_driver_instance();
        con = driver->connect("tcp://10.0.0.31:3306", "root", "haifan123!@#");
        /* Connect to the MySQL test database */
        con->setSchema("hf_face_sys");

        std::cout << "start " << start <<" -> " << limit << std::endl;
        
        stmt = con->createStatement();
        string sql = "select * from faces_bigdata limit " + to_string(start) + "," + to_string(limit);
        res = stmt->executeQuery(sql.c_str());
        bool first = true;
        string last;
        while (res->next())
        {
            if(first) {
                cout << "first id = " << res->getString(1) << endl;
                first = false;
            }
            last = res->getString(1);
        }
        cout << "last id = " << last << endl;
        std::cout << "this_thread id = " << std::this_thread::get_id() << std::endl;
        delete res;
        delete stmt;
        delete con;
    }
    catch (sql::SQLException &e)
    {
        cout << "# ERR: SQLException in " << __FILE__;
        cout << "(" << __FUNCTION__ << ") on line " << __LINE__ << endl;
        cout << "# ERR: " << e.what();
        cout << " (MySQL error code: " << e.getErrorCode();
        cout << ", SQLState: " << e.getSQLState() << " )" << endl;
    }

    
    std::ostringstream oss;
	oss << std::this_thread::get_id();
	std::string stid = oss.str();
	unsigned long long tid = std::stoull(stid);

    return tid;
}

int main(void)
{
    ThreadPool *executor = new ThreadPool(4);
    int count = read_dat_count();

    std::cout << "count = " << count << std::endl;

    int limit = ceil(count / 4);

    std::cout << "limit = " << limit << std::endl;

    auto res1 = executor->push_task(read_sql_dat, 0, limit);
    auto res2 = executor->push_task(read_sql_dat, limit, limit);
    auto res3 = executor->push_task(read_sql_dat, limit * 2, limit);
    auto res4 = executor->push_task(read_sql_dat, limit * 3, limit);

    int r1 = res1.get();
    int r2 = res2.get();
    int r3 = res3.get();
    int r4 = res4.get();
 
    std::cout << "res1 = " << r1 << std::endl;
    std::cout << "res2 = " << r2 << std::endl;
    std::cout << "res3 = " << r3 << std::endl;
    std::cout << "res4 = " << r4 << std::endl;

    return EXIT_SUCCESS;
}

3. CMakeLists.txt

project(redis-test)

cmake_minimum_required(VERSION 2.6.0 FATAL_ERROR)


set(CMAKE_CXX_STANDARD 11)
set(CMAKE_CXX_STANDARD_REQUIRED ON)

set (CMAKE_EXE_LINKER_FLAGS_RELEASE  "${CMAKE_EXE_LINKER_FLAGS_RELEASE} ")
set(CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE} -O3 -std=c++11 -Wall ")
set ( CMAKE_EXE_LINKER_FLAGS_DEBUG  "${CMAKE_EXE_LINKER_FLAGS_DEBUG} -fsanitize=address -fsanitize=undefined ")
set(CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG}  -std=c++11 -Wall -O0 -fno-omit-frame-pointer -fsanitize=address -fsanitize=undefined -D__FORTIFY_SOURCE=2 -rdynamic -DDEBUG")

include_directories("~/haifan/zhouyong/c++/redis-test/")
include_directories("~/haifan/zhouyong/c++/redis-test/redis-plus-plus/src/")
include_directories("~/haifan/zhouyong/c++/redis-test/redis-plus-plus/src/sw/redis++/no_tls")
link_directories("/home/haifan/haifan/zhouyong/c++/redis-test/redis-plus-plus/build/")
link_directories("/home/haifan/haifan/zhouyong/c++/redis-test/hiredis/")


find_package(OpenCV  REQUIRED)

include(CMakeToolsHelpers OPTIONAL)

include_directories(${OpenCV_INCLUDE_DIRS})

add_executable(multi-mysql-test main.cpp)
# add_executable(hfTest test.cpp)
# add_executable(hfTest2 test2.cpp)

target_link_libraries(multi-mysql-test glog cryptopp ${OpenCV_LIBS}  uuid mysqlcppconn jsoncpp pthread redis++ hiredis)

 

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

C++ MYSQL 多线程并发查询处理数据 的相关文章

  • WPF DataGrid 多选

    我读过几篇关于这个主题的文章 但很多都是来自 VS 或框架的早期版本 我想做的是从 dataGrid 中选择多行并将这些行返回到绑定的可观察集合中 我尝试创建一个属性 类型 并将其添加到可观察集合中 它适用于单个记录 但代码永远不会触发多个
  • C# 异步等待澄清?

    我读了here http blog stephencleary com 2012 02 async and await html that 等待检查等待的看看它是否有already完全的 如果 可等待已经完成 那么该方法将继续 运行 同步
  • 没有特殊字符的密码验证器

    我是 RegEx 的新手 已经进行了大量搜索 但没有找到任何具体内容 我正在编写一个验证密码字符串的正则表达式 可接受的字符串必须至少具有 4 种字符类型中的 3 种 数字 小写字母 大写字母 特殊字符 我对包含有一个想法 也就是说 如果这
  • 机器Epsilon精度差异

    我正在尝试计算 C 中双精度数和浮点数的机器 epsilon 值 作为学校作业的一部分 我在 Windows 7 64 位中使用 Cygwin 代码如下 include
  • std::list 线程push_back、front、pop_front

    std list 线程安全吗 我假设不是这样 所以我添加了自己的同步机制 我认为我有正确的术语 但我仍然遇到问题 每个函数都由单独的线程调用 Thread1 不能等待 它必须尽可能快 std list
  • 如何从本机 C(++) DLL 调用 .NET (C#) 代码?

    我有一个 C app exe 和一个 C my dll my dll NET 项目链接到本机 C DLL mynat dll 外部 C DLL 接口 并且从 C 调用 C DLL 可以正常工作 通过使用 DllImport mynat dl
  • 如何在 C++ 中标记字符串?

    Java有一个方便的分割方法 String str The quick brown fox String results str split 在 C 中是否有一种简单的方法可以做到这一点 The 增强分词器 http www boost o
  • 对类 static constexpr 结构的未定义引用,g++ 与 clang

    这是我的代码 a cp p struct int2 int x y struct Foo static constexpr int bar1 1 static constexpr int2 bar2 1 2 int foo1 return
  • 访问外部窗口句柄

    我当前正在处理的程序有问题 这是由于 vista Windows 7 中增强的安全性引起的 特别是 UIPI 它阻止完整性级别较低的窗口与较高完整性级别的窗口 对话 就我而言 我想告诉具有高完整性级别的窗口进入我们的应用程序 它在 XP 或
  • WPF 数据绑定到复合类模式?

    我是第一次尝试 WPF 并且正在努力解决如何将控件绑定到使用其他对象的组合构建的类 例如 如果我有一个由两个单独的类组成的类 Comp 为了清楚起见 请注意省略的各种元素 class One int first int second cla
  • ASP.NET Core 3.1登录后如何获取用户信息

    我试图在登录 ASP NET Core 3 1 后获取用户信息 如姓名 电子邮件 id 等信息 这是我在登录操作中的代码 var claims new List
  • 使用 C# 中的 CsvHelper 将不同文化的 csv 解析为十进制

    C 中 CsvHelper 解析小数的问题 我创建了一个从 byte 而不是文件获取 csv 文件的类 并且它工作正常 public static List
  • 如何获取 EF 中与组合(键/值)列表匹配的记录?

    我有一个数据库表 其中包含每个用户 年份组合的记录 如何使用 EF 和用户 ID 年份组合列表从数据库获取数据 组合示例 UserId Year 1 2015 1 2016 1 2018 12 2016 12 2019 3 2015 91
  • 空指针与 int 等价

    Bjarne 在 C 编程语言 中写道 空指针与整数零不同 但 0 可以用作空指针的指针初始值设定项 这是否意味着 void voidPointer 0 int zero 0 int castPointer reinterpret cast
  • 为什么使用小于 32 位的整数?

    我总是喜欢使用最小尺寸的变量 这样效果就很好 但是如果我使用短字节整数而不是整数 并且内存是 32 位字可寻址 这真的会给我带来好处吗 编译器是否会做一些事情来增强内存使用 对于局部变量 它可能没有多大意义 但是在具有数千甚至数百万项的结构
  • 如何在 Linq to SQL 中使用distinct 和 group by

    我正在尝试将以下 sql 转换为 Linq 2 SQL select groupId count distinct userId from processroundissueinstance group by groupId 这是我的代码
  • C++ 继承的内存布局

    如果我有两个类 一个类继承另一个类 并且子类仅包含函数 那么这两个类的内存布局是否相同 e g class Base int a b c class Derived public Base only functions 我读过编译器无法对数
  • 使用特定参数从 SQL 数据库填充组合框

    我在使用参数从 sql server 获取特定值时遇到问题 任何人都可以解释一下为什么它在 winfom 上工作但在 wpf 上不起作用以及我如何修复它 我的代码 private void UpdateItems COMBOBOX1 Ite
  • C++ 中的参考文献

    我偶尔会在 StackOverflow 上看到代码 询问一些涉及函数的重载歧义 例如 void foo int param 我的问题是 为什么会出现这种情况 或者更确切地说 你什么时候会有 对参考的参考 这与普通的旧参考有何不同 我从未在现
  • DotNetZip:如何提取文件,但忽略zip文件中的路径?

    尝试将文件提取到给定文件夹 忽略 zip 文件中的路径 但似乎没有办法 考虑到其中实现的所有其他好东西 这似乎是一个相当基本的要求 我缺少什么 代码是 using Ionic Zip ZipFile zf Ionic Zip ZipFile

随机推荐

  • vue实现鼠标放上去就有提示_Vue实现鼠标经过文字显示悬浮框效果的示例代码

    需求 在所做的Vue项目中 需要在鼠标移动文字框的时候显示一些详细信息 最终实现的效果如下 鼠标经过button的时候 可以在光标附近显示出一个悬浮框 显示框里面显示时间和值的信息 鼠标移出button元素的时候 这个显示框会消失 分析 涉
  • C++编写优先队列打印任务

    打印机的打印队列中 每一个打印任务都有一个优先级 为1 9的一个整数 9的优先级最高 1的优先级最低 打印按如下方法进行 1 取出打印队列中队首的打印任务J 2 如果打印队列中存在优先级高于J的打印任务 则将J移动到打印队列的队尾 否则 打
  • 微软鼠标测试软件,第一款win8鼠标:微软Sculpt全球首测

    1Sculpt触控鼠标 带来全新感受 中关村在线键鼠频道原创 微软硬件在外设产品研发上 一直致力于以领先的科技带给用户超凡的体验 从早期的IE3 0 到越野蓝影 再到Arc Touch Touch Mouse等等 微软硬件在的每一次技术革命
  • 企业怎么选择固定资产管理系统

    资产管理 无论在企业还是在事业单位 都是管理人员重要的工作 随着计算机技术的普及 资产管理系统 已经有了相对清晰的管理流程及其配套的管理软件 资产管理系统是面向资产密集型企业的企业信息化解决方案的总称 它以提高资产管理效率 降低企业管理成本
  • VS2019 preview 卡在正在加载解决方案

    VS2019 解决方案 或者项目 卡 正在加载 的解决办法 1 关闭VS 2 去C Users
  • 微信小程序css篇----定位(position)

    昨天2017的微信公开课pro如期进行了 小程序将于2017年1月9日对个人开放 公司项目的demo版做了个大概 过程中花的时间最多的还是页面布局 所以后面将花一段时间将css的属性在小程序里过一篇 虽然小程序里面对于css支持 但没有说明
  • 使用labview 的http协议实现post和get,带解析

    1 创建一个新项目 右键点击我的电脑 新建web服务 然后就弹出web资源和启动VI 2 web资源新建一个VI HTTPMethed 1 vi 用来相应post data的数据 右键可以显示方法url HTTPMethed 1内容如下 3
  • shell脚本实现文件移动、复制等操作

    如题 在此做一记录 方便查阅 bin bash 将一个目录下的一些文件移动到另一个目录下 raw dir home liuyi evt test 可修改绝对路径 mkdir home liuyi evt bp 创建新的文件目录 for el
  • 四、spring源码循环依赖的处理之doCreateBean方法的执行流程(文字描述)

    还写了一篇 内容和这个差不多的 emm 那篇更简洁 算是半伪码形式 https blog csdn net qq 36951116 article details 100078947 其实createBean方法没做什么事 主要就是 1 调
  • Android---SpringBoot实现前后端数据交互

    Android SpringBoot实现前后端数据交互 星光不问赶路人 时间不负有心人 这篇是针对android传数据到后台springboot 使用Xutils框架 使用Xutils框架 关于xutils的使用这是老师的博客大家可以看看
  • 【1024狂欢】力扣经典链表OJ题合集

    现在的力扣题的源代码我会全部一并上传至我的码云仓库里面 点我看仓库 写在前面 首先祝各位程序猿1024狂欢节快乐鸭 这是属于我们的节日 为了致敬1024 今天的力扣系列不再是一题了 而是多个题的组合 也是与我们最近更新的内容梦幻联动 祝大家
  • 节后充电!卷王必看的前端进阶指南来喽~

    本文推荐最近在考虑新机会的小伙伴阅读 前言 上 周和部门BP聊天 她说最近在boss上放出一个初级前端岗位 平均每天都能收到500多份简历 前端市场越来越卷 跳槽前做好技术进阶突击 才能稳拿offer 这里有一份我爆肝两个月整理出的 202
  • 使用 C# 下载文件的十八般武艺

    文件下载是一个软件开发中的常见需求 本文从最简单的下载方式开始步步递进 讲述了文件下载过程中的常见问题并给出了解决方案 并展示了如何使用多线程提升 HTTP 的下载速度以及调用 aria2 实现非 HTTP 协议的文件下载 简单下载 在 N
  • 移动端(H5)手搓弹框

  • js通过文件的url下载文件到本地

    1 美图 2 概述 a href download papers abc doc 点击链接下载 a
  • 什么是哈夫曼编码

    在上一篇 我们介绍了一种特殊的数据结构 哈夫曼树 也被称为最优二叉树 没看过的小伙伴可以点击链接 什么是哈夫曼树 那么 这种数据结构究竟有什么用呢 我们今天就来揭晓答案 计算机系统是如何存储信息的呢 计算机不是人 它不认识中文和英文 更不认
  • HDFS 分布式文件系统详解

    1 HDFS概述 Hadoop 分布式系统框架中 首要的基础功能就是文件系统 在 Hadoop 中使用 FileSystem 这个抽象类来表示我们的文件系统 这个抽象类下面有很多子实现类 究竟使用哪一种 需要看我们具体的实现类 在我们实际工
  • 理解React的虚拟DOM

    一 背景 React是一个用于构建用户界面的JavaScript库 区别于老的前端开发技术 其最核心的就是引入了虚拟DOM的技术 为了对React有一个比较全面和深入的了解 所以把最近学习React虚拟DOM的知识 做个笔记 仅供学习 二
  • LRU LFU 概念、底层原理及其实现 超详细~

    0 前置提要 本篇约为8650字 阅读完需要约40 60分钟 主要介绍页面置换算法 LRU和LFU的原理及其实现 对应leetcode140和460 如果能给个赞就更好了 1 从内存置换算法说起 计算机的运行的程序和数据保存在内存中 内存的
  • C++ MYSQL 多线程并发查询处理数据

    1 ThreadPool hpp pragma once ifndef THREAD POOL H define THREAD POOL H include