英文:
C/C++ multithreading - run threads sequentially, sorted based on a particular variable
问题
我正在运行一个C++多线程应用程序。线程数量是可变的,每个线程都有自己的一组变量,这些变量是从一个JSON类型的命令行参数中解析出来的。我必须根据这些变量按降序顺序依次运行这些线程(这可能会破坏多线程的目的,但出于其他用例的需要,必须保持这种方式)。
举个例子,假设命令行参数如下所示:
{"ID":[1,4,3,2]}
我必须按照降序排序的ID [4,3,2,1] 启动与每个ID对应的线程。从ID=4开始;在与ID=4对应的线程完成后,我必须运行ID=3的线程,之后运行ID=2的线程,然后运行ID=1的线程。
对于这个问题,一个好的设计是什么?
英文:
I am running a multithreaded application in C++. The number of threads is variable and each thread has it's own set of variables, parsed from a JSON type command line argument. I have to run these threads sequentially (may defeat the purpose of multithreading, but need to keep it this way for other use cases) based on the variables in descending order.
Say for example, the command line arg is something like:
{"ID":[1,4,3,2]}
I have to start a thread corresponding to each ID sorted in descending order [4,3,2,1]. Starting from ID=4; after thread corresponding to ID=4 finishes, I have to run a thread for ID=3, after this finishes, run thread for ID=2 and then thread for ID=1.
What would be a good design for this problem?
答案1
得分: 1
以下是代码的翻译部分:
这是一个不使用任何C++20特性的基本解决方案,其中一个缺点是您的线程函数必须具有特定类型,这种情况下是没有参数的无返回值函数,但您可以扩展这个类以支持具有任意参数的函数。
#include <algorithm>
#include <iostream>
#include <thread>
#include <vector>
using namespace std;
class ThreadScheduler {
public:
using ThreadFunction = void(*)();
vector<pair<int, ThreadFunction>> m_threads;
public:
void add_thread(int id, ThreadFunction f) {
m_threads.emplace_back(id, f);
}
template <class Compare>
void run_seq(Compare comp) {
using PairRef = reference_wrapper<pair<int, ThreadFunction>>;
vector<PairRef> temp_threads(m_threads.begin(), m_threads.end());
sort(
temp_threads.begin(), temp_threads.end(),
[&](PairRef p1, PairRef p2) {
return comp(p1.get().first, p2.get().first);
}
);
for (auto& t : temp_threads) {
t.get().second();
}
}
void run_parallel() {
vector<thread> thread_handles;
for (auto& t : m_threads) {
thread_handles.emplace_back(t.second);
}
for (auto& th : thread_handles) {
th.join();
}
}
};
int main() {
ThreadScheduler ts;
ts.add_thread(4, []() {
cout << "4\n";
});
ts.add_thread(12, []() {
cout << "12\n";
});
ts.add_thread(2, []() {
cout << "2\n";
});
ts.add_thread(8, []() {
cout << "8\n";
});
ts.run_seq(greater<int>());
ts.run_parallel();
return 0;
}
请注意,以上是您提供的C++代码的翻译部分。
英文:
Here's a basic solution without using any C++20 features, one drawback is that your thread functions must be of a specific type, none/void-returning with no parameters in this case, but you could extend this class to support functions of arbitrary parameters.
#include <algorithm>
#include <iostream>
#include <thread>
#include <vector>
using namespace std;
class ThreadScheduler {
public:
using ThreadFunction = void(*)();
vector<pair<int, ThreadFunction>> m_threads;
public:
void add_thread(int id, ThreadFunction f) {
m_threads.emplace_back(id, f);
}
template <class Compare>
void run_seq(Compare comp) {
using PairRef = reference_wrapper<pair<int, ThreadFunction>>;
vector<PairRef> temp_threads(m_threads.begin(), m_threads.end());
sort(
temp_threads.begin(), temp_threads.end(),
[&](PairRef p1, PairRef p2) {
return comp(p1.get().first, p2.get().first);
}
);
for (auto& t : temp_threads) {
t.get().second();
}
}
void run_parallel() {
vector<thread> thread_handles;
for (auto& t : m_threads) {
thread_handles.emplace_back(t.second);
}
for (auto& th : thread_handles) {
th.join();
}
}
};
int main() {
ThreadScheduler ts;
ts.add_thread(4, []() {
cout << "4\n";
});
ts.add_thread(12, []() {
cout << "12\n";
});
ts.add_thread(2, []() {
cout << "2\n";
});
ts.add_thread(8, []() {
cout << "8\n";
});
ts.run_seq(greater<int>());
ts.run_parallel();
return 0;
}
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论