当前位置: 首页 > news >正文

简易银行系统->多线程高并发

灵机一动整活的时候 最有写代码的动力的说:leetcode/bank_transaction at main · lvy010/leetcode

我们可以很简单的借助数组ac lc2043

C++

using namespace std;class Bank {vector<long long> b;bool ok(int a){ return 1 <= a && a <= (int)b.size(); }
public:Bank(vector<long long>& balance): b(balance) {}bool transfer(int a, int c, long long m){if(!ok(a) || !ok(c) || b[a-1] < m) return false;b[a-1] -= m; b[c-1] += m; return true;}bool deposit(int a, long long m){if(!ok(a)) return false;b[a-1] += m; return true;}bool withdraw(int a, long long m){if(!ok(a) || b[a-1] < m) return false;b[a-1] -= m; return true;}
};

那么考虑上多线程高并发应该如何进一步设计出代码呢?

  • 可以采用线程池与细粒度账户级锁,按序获取双锁避免死锁,确保事务原子性与数据一致性
    • 通过 future 异常传播与可配置并发度,实现高吞吐、可扩展、可观测的多线程高并发交易处理架构

      thread_pool.hpp

      C++

      // 线程池:固定线程数,支持 submit(lambda) 返回 std::future
      #pragma once#include <condition_variable>
      #include <cstddef>
      #include <future>
      #include <mutex>
      #include <queue>
      #include <thread>
      #include <type_traits>
      #include <utility>
      #include <vector>class ThreadPool {
      public:explicit ThreadPool(std::size_t numThreads) {if (numThreads == 0) {numThreads = 1;}try {for (std::size_t i = 0; i < numThreads; ++i) {workers.emplace_back([this]{ this->workerLoop(); });}} catch (...) {stop();throw;}}ThreadPool(const ThreadPool&) = delete;ThreadPool& operator=(const ThreadPool&) = delete;~ThreadPool() {stop();}template <class F, class... Args,class R = std::invoke_result_t<std::decay_t<F>, std::decay_t<Args>...>>std::future<R> submit(F&& f, Args&&... args) {auto taskPtr = std::make_shared<std::packaged_task<R()>>(std::bind(std::forward<F>(f), std::forward<Args>(args)...));std::future<R> fut = taskPtr->get_future();{std::unique_lock<std::mutex> lk(mtx);if (isStopping) {throw std::runtime_error("ThreadPool stopped");}tasks.emplace([taskPtr]{try { (*taskPtr)(); } catch (...) { throw; }});}cv.notify_one();return fut;}void stop() noexcept {{std::unique_lock<std::mutex> lk(mtx);if (isStopping) return;isStopping = true;}cv.notify_all();for (std::thread& t : workers) {if (t.joinable()) t.join();}workers.clear();}private:void workerLoop() {while (true) {std::function<void()> task;{std::unique_lock<std::mutex> lk(mtx);cv.wait(lk, [this]{ return isStopping || !tasks.empty(); });if (isStopping && tasks.empty()) return;task = std::move(tasks.front());tasks.pop();}try {task();} catch (...) {// 任务异常在 future 中可见,这里不吞异常}}}std::vector<std::thread> workers;std::queue<std::function<void()>> tasks;std::mutex mtx;std::condition_variable cv;bool isStopping {false};
      };

      bank.cpp

      C++

      #pragma once#include <algorithm>
      #include <cstddef>
      #include <mutex>
      #include <stdexcept>
      #include <utility>
      #include <vector>class ConcurrentBank {
      public:explicit ConcurrentBank(std::vector<long long> initialBalances): balances(std::move(initialBalances)), accountMutexes(balances.size()) {}std::size_t numAccounts() const noexcept { return balances.size(); }bool deposit(std::size_t accountIndex, long long amount) {if (!isValidAccount(accountIndex) || amount <= 0) return false;std::lock_guard<std::mutex> g(accountMutexes[accountIndex]);balances[accountIndex] += amount;return true;}bool withdraw(std::size_t accountIndex, long long amount) {if (!isValidAccount(accountIndex) || amount <= 0) return false;std::lock_guard<std::mutex> g(accountMutexes[accountIndex]);if (balances[accountIndex] < amount) return false;balances[accountIndex] -= amount;return true;}bool transfer(std::size_t fromIndex, std::size_t toIndex, long long amount) {if (amount <= 0) return false;if (!isValidAccount(fromIndex) || !isValidAccount(toIndex)) return false;if (fromIndex == toIndex) return true; // 自转账视为无操作std::size_t a = std::min(fromIndex, toIndex);std::size_t b = std::max(fromIndex, toIndex);std::unique_lock<std::mutex> lockA(accountMutexes[a]);std::unique_lock<std::mutex> lockB(accountMutexes[b]);if (fromIndex == a) {if (balances[fromIndex] < amount) return false;balances[fromIndex] -= amount;balances[toIndex] += amount;} else {if (balances[fromIndex] < amount) return false;balances[fromIndex] -= amount;balances[toIndex] += amount;}return true;}long long getBalance(std::size_t accountIndex) const {if (!isValidAccount(accountIndex)) throw std::out_of_range("bad account");std::lock_guard<std::mutex> g(accountMutexes[accountIndex]);return balances[accountIndex];}long long sumBalances() const {// 顺序加锁,避免死锁for (std::size_t i = 0; i < accountMutexes.size(); ++i) {accountMutexes[i].lock();}long long s = 0;for (long long v : balances) s += v;for (std::size_t i = accountMutexes.size(); i-- > 0;) {accountMutexes[i].unlock();}return s;}private:bool isValidAccount(std::size_t accountIndex) const noexcept {return accountIndex < balances.size();}mutable std::vector<std::mutex> accountMutexes;std::vector<long long> balances;
      };
      http://www.dtcms.com/a/533312.html

      相关文章:

    • 【系统分析师】高分论文:论基于构件的软件开发(气象灾害影响评估系统)
    • 【java面向对象进阶】------多态综合案例
    • 做一个内容网站多少钱wordpress调用导航
    • 惠州网站开发公司电话个人兴趣图片集网站建设
    • C++ list 类的使用
    • 怎么利用QQ空间给网站做排名没有专项备案的网站
    • 显示官网字样的网站怎么做wordpress 多站点主题
    • 如何建设一个新的网站快手推广软件免费版
    • 国内十大搜索引擎网站安徽网络关键词优化
    • 【Linux】定制Linux系统
    • 个人网站备案取消网站建设管理分工
    • 企业网站建设的趋势手机网站建设的整体流程图
    • 松原做招聘的网站有哪些系统优化的意义
    • 业务流程图 —— 讲清“谁做了什么事”
    • 天津网站建设咨询杭州景观设计公司排行
    • 10.5 小项目:如何用 JavaScript 实现一个高效的时间+Token过期容器?
    • 网站备案帐号找回密码免费友链平台
    • Every other Cycle Command Input(隔循环命令输入)
    • 更换docker默认镜像仓库地址方法
    • 福建省交通建设质量安全监督局网站软文写作技巧
    • 装饰公司营销型网站设计网站图片等比缩小
    • 高端网站制作价格大型大型网站建设方案ppt模板
    • 【底层机制】Linux内核4.10版本的完整存储栈架构讲解--用户空间到物理设备完整IO路径
    • nodejs 使用speaker + ffmpeg 实现静默播放MP3
    • 【大模型应用开发 LangChain模型输出属性速查表】
    • 南京 电子商务网站WordPress实现微信一键登录
    • 豫icp郑州网站建设做视频网站要什么
    • 商丘手机网站制作西安怡佳然网络科技有限公司
    • 开发制作一个网站北京做网站的公司商集客电话
    • 第七章:理解篇 - 对接云端语音识别,让助手“听懂”人话