【发布时间】:2022-01-11 11:27:24
【问题描述】:
我在 Linux 上使用 C++,我需要开发一个通用库来简化多线程开发。
嗯,我知道C++11中有一些多线程机制,比如std::async,std::future等。但是由于一些历史原因,我不得不使用pthread。
基本上,我想做的是制作一个非常简单的模板函数,有点像std::future。在这里。
template<typename S>
struct signature;
template<typename R, typename... Args>
struct signature<R(*)(Args...)> {
using return_type = R;
using argument_type = std::tuple<R(*)(Args...), Args...>; // f, args...
};
template<typename F, typename... Args>
void func(F* f, Args&&... args) {
typename signature<decltype(f)>::argument_type tp = std::make_tuple(f, std::forward<Args>(args)...);
pthread_t td;
pthread_create(&td, nullptr, [](void *p){
auto param = static_cast<typename signature<decltype(f)>::argument_type*>(p);
std::get<0>(*param)(std::get<1>(*param)); // ???
return (void*)nullptr;
}, &tp);
}
void f(int a) {}
void f2(int a, int b) {}
int main() {
func(f, 1);
// func(f2, 2, 2); ERROR!
return 0;
}
总之,我尝试将函数的参数包装成一个元组,并将元组传递给pthread_create的第三个参数,即labmda。
所以在这段代码中,std::get<0>(*param) 是函数,元组*param 的其余部分是应该传递给函数的参数列表。但我不知道如何扩展它。很明显,std::get<0>(*param)(std::get<1>(*param)); 不行,因为它只能处理带有一个参数的函数。如果我想传递一个带有两个参数的函数,我会得到一个错误。
那么如何扩展那里的元组呢?
顺便说一句,请忽略其他问题,例如为什么不打电话给pthread_join。我只是在这里删除它们以最小化我的帖子。
【问题讨论】:
-
您在寻找
std::apply吗?顺便说一句,为什么要使用 pthreads 而不是 C++ 线程? -
@Daniel Langr 甚至 C++20
std::jthread加入其析构函数。 -
@DanielLangr 哦,你是对的,我正在寻找它。为什么不使用
std::thread?大声笑,那是因为在我的项目中,我既不使用std::thread也不使用pthread,这是pthread类似的旧东西......由于某些历史原因,我无权更改它......我的公司开发了它自己的线程,其中包含许多指标的东西。
标签: c++ templates tuples c++14 template-meta-programming