简体   繁体   English

c++多线程程序架构

[英]c++ multi-threading program architecture

I am currently practicing the use of multiple threads in C++.我目前正在练习在 C++ 中使用多线程。 The program is simplified as follow.程序简化如下。 In this case, I have a global variable Obj , and within each task, a get function is processed by thread and thread detach will be called after.在这种情况下,我有一个全局变量Obj ,并且在每个任务中,线程处理一个get函数,之后将调用线程分离。

In practice, get may take a great amount of time to run.在实践中, get可能需要很长时间才能运行。 If there are many tasks, get will be called repetitively (since each task has its own get function).如果任务很多,get会被重复调用(因为每个任务都有自己的get函数)。 I wonder if I can design a program where when one task has already obtained the data using get function and the data has been wrote to obj.text , then the rest of tasks can directly access or wait for the data from obj.text .我想知道我是否可以设计一个程序,当一个任务已经使用get函数获取数据并且数据已经写入obj.text时,其余任务可以直接访问或等待来自obj.text的数据。

Can I use std::shared_ptr, std::future, std::async in c++ to implement this?我可以在 c++ 中使用std::shared_ptr, std::future, std::async来实现这个吗? If so, how to design the program?如果是这样,如何设计程序? Any advice is greatly appreciated.任何意见是极大的赞赏。

#include <chrono>
#include <future>
#include <iostream>
#include <memory>
#include <thread>
#include <vector>
using namespace std;

class Info {
public:
  Info() { Ids = 10; };

  int Ids;
  std::string text;
};

Info Objs;

class Module {
public:
  Module() {}
  virtual void check(int &id){};
  virtual void get(){};
};

class task1 : public Module {
public:
  task1() { std::cout << "task1" << std::endl; }
  void check(int &id) override {
    thread s(&task1::get, this);
    s.detach();
  };

  // The function will first do some other work (here, I use sleep to represent
  // that) then set the value of Objs.text
  void get() override {
    // The task may take 2 seconds , So use text instead
    std::this_thread::sleep_for(std::chrono::seconds(5));
    Objs.text = "AAAA";
    std::cout << Objs.text << std::endl;
  };
};

class task2 : public Module {
public:
  task2() { std::cout << "task2" << std::endl; }
  void check(int &id) override {
    thread s(&task2::get, this);
    s.detach();
  };
  // The function will first do some other work (here, I use sleep to represent
  // that) then set the value of Objs.text
  void get() {
    std::this_thread::sleep_for(std::chrono::seconds(5));
    Objs.text = "AAAA";
    std::cout << Objs.text << std::endl;
  };
};

int main() {
  std::vector<std::unique_ptr<Module>> modules;

  modules.push_back(std::make_unique<task1>());
  modules.push_back(std::make_unique<task2>());

  for (auto &m : modules) {
    m->check(Objs.Ids);
  }

  std::this_thread::sleep_for(std::chrono::seconds(12));
  return 0;
}

It is a plain producer-consumer problem.这是一个简单的生产者-消费者问题。

You have multiple “get()” producers.你有多个“get()”生产者。 And did not implemented consumers yet.并且还没有实现消费者。

First, you should have multiple “Info” for multithread.首先,你应该有多个多线程的“信息”。 If there is only one Info, multithread programming is useless.如果只有一个Info,多线程编程就没用了。 I recommend “concurrent_queue”.我推荐“concurrent_queue”。

Second, “detach()” is not a good idea.其次,“detach()”不是一个好主意。 You can't manage child threads.您无法管理子线程。 You'd better use “join()”你最好使用“join()”

My code sample follows.我的代码示例如下。 I used Visual Studio 2022我使用了 Visual Studio 2022

#include <chrono>
#include <iostream>
#include <thread>
#include <vector>
#include <concurrent_queue.h>
using namespace std;

class Info {
public:
    Info() { Ids = 10; };
    int Ids;
    std::string text;
};

concurrency::concurrent_queue<Info> Objs;

void producer()
{
    while (true) {
        Info obj;
        std::this_thread::sleep_for(std::chrono::seconds(5));
        obj.text = "AAAA\n";
        Objs.push(obj);
    }
}

void consumer()
{
    while (true) {
        std::this_thread::sleep_for(std::chrono::seconds(1));
        Info obj;
        bool got_it = Objs.try_pop(obj);
        if (got_it) {
            std::cout << obj.text;
        }
    }
}

int main() {
    const int NUM_CORES = 6;
    std::vector<std::thread> threads;
    for (int i = 0; i < NUM_CORES / 2; ++i)
        threads.emplace_back(producer);
    for (int i = 0; i < NUM_CORES / 2; ++i)
        threads.emplace_back(consumer);
    for (auto& th : threads) th.join();
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM