gpt4 book ai didi

c++ - C++ 的通用线程 C 包装器函数

转载 作者:太空宇宙 更新时间:2023-11-04 11:55:06 25 4
gpt4 key购买 nike

在这里,我为 C 线程函数 pthread_create() 编写了一个线程包装器。它将允许在任何对象上调用任何方法并将任意数量的参数传递给该方法。 API 是:

template <typename T, typename R, typename... ATs>
pthread_t NewThread(T *obj, R (T::*mem)(ATs...), ATs... args);

模板如下:

template<unsigned int i>  
class TupleUnpack
{
public:
template<typename R, typename ...ATs, typename ...T_function_arguments>
inline static R unpack (R (*function) (ATs...),
std::tuple<ATs...> arguments_tuple,
T_function_arguments ...function_arguments)
{
return TupleUnpack<i-1>::unpack (function, arguments_tuple, std::get<i-1> (arguments_tuple), function_arguments...);
}
};

template<>
class TupleUnpack<0>
{
public:
template<typename R, typename ...ATs, typename ...T_function_arguments>
inline static R unpack (R (*function) (ATs...),
std::tuple<ATs...> arguments_tuple,
T_function_arguments ...function_arguments)
{
return function (function_arguments...);
}
};
class CallCaller
{
virtual bool dispatch (void)=0;
};

template<typename T,typename R,typename ...ATs>
class Call : public CallCaller
{
public:
Call (T *obj,R (*function) (ATs...),ATs... arguments) :obj(obj),function (function),tuplearg (arguments...) {}

~Call() {}
bool dispatch (void)
{
return TupleUnpack<sizeof ...(ATs)>::unpack (this->function, this->tuplearg);
}

private:
std::tuple<ATs...> tuplearg;
R (*function) (ATs...);

T *obj;
};

void *test(int d,double sf)
{
std::cout<<"yay my thread runs d="<<d<<" sf="<<sf<<std::endl;
}

template<typename T,typename R,typename ...ATs>
void* stub (void* vp)
{

Call<T,R,ATs...>* call = static_cast<Call<T,R,ATs...>*>(vp);
call->dispatch();
delete call;
pthread_exit (0);

}
template <typename T, typename R, typename... ATs>
pthread_t NewThread(T *ob, R (T::*mem)(ATs...), ATs... args)
{
pthread_t tid;
R (*func) (ATs...);
Call<T,R,ATs...> *task=new Call<T,R,ATs...>(ob,&test,args...);

pthread_create(&tid, nullptr, stub<T,R,ATs...>, task) ;

return tid;
}

CPP文件如下:

#include <tr1/tuple>
#include <utility>
#include <iostream>
#include <pthread.h>
#include <tuple>
#include <type_traits>
#include <utility>
#include "NewThread.hpp"

class X
{
public:
void *method(int a, double x)
{
std::cout<<"yay my tread runs a="<<a<<" x="<<x<<std::endl;
}

};

int main()
{
X x;
int i;
pthread_t tid = NewThread(&x, &X::method, 1234, 3.14);



pthread_join(tid,NULL);

std::cout<<"Thread Ended "<<tid<<std::endl;
return 0;
}

我正在尝试使用参数调用 x::method()。如您所见,我有一个类似于 x::method()test() 函数,只是为了证明我的线程正在运行。但我希望能够调用 x::method()。谁能指导我?

本质上我当前的输出是:

yay my thread runs d=1234 sf=3.14
Thread Ended 139766222432000

我希望我的输出是

yay my thread runs a=1234 x=3.14
Thread Ended 139766222432000

最佳答案

所以这个

R (*function) (ATs...);

是一个函数指针,但是你需要一个成员函数指针

R (T::*function) (ATs...);

要调用成员函数指针,您需要一个对象,并且必须使用以下语法调用它:

self->*function(function_arguments...);

备注->*语法在这里。

所以我加了一个T* self参数 TupleUnpack<>::unpack并在 Call<>::dispatch 中调用它与 obj成员。现在,我可以替换 test功能与 mem NewThread 中的参数.

这是一个补丁:

diff --git a/NewThread.hpp b/NewThread.hpp
index e121294..768f7d9 100644
--- a/NewThread.hpp
+++ b/NewThread.hpp
@@ -5,12 +5,12 @@ template<unsigned int i>
class TupleUnpack
{
public:
- template<typename R, typename ...ATs, typename ...T_function_arguments>
- inline static R unpack (R (*function) (ATs...),
+ template<typename T, typename R, typename ...ATs, typename ...T_function_arguments>
+ inline static R unpack (T* self, R (T::*function) (ATs...),
std::tuple<ATs...> arguments_tuple,
T_function_arguments ...function_arguments)
{
- return TupleUnpack<i-1>::unpack (function, arguments_tuple, std::get<i-1> (arguments_tuple), function_arguments...);
+ return TupleUnpack<i-1>::unpack (self, function, arguments_tuple, std::get<i-1> (arguments_tuple), function_arguments...);
}
};

@@ -18,12 +18,12 @@ template<>
class TupleUnpack<0>
{
public:
- template<typename R, typename ...ATs, typename ...T_function_arguments>
- inline static R unpack (R (*function) (ATs...),
+ template<typename T, typename R, typename ...ATs, typename ...T_function_arguments>
+ inline static R unpack (T* self, R (T::*function) (ATs...),
std::tuple<ATs...> arguments_tuple,
T_function_arguments ...function_arguments)
{
- return function (function_arguments...);
+ return (self->*function) (function_arguments...);
}
};
class CallCaller
@@ -35,19 +35,17 @@ template<typename T,typename R,typename ...ATs>
class Call : public CallCaller
{
public:
- Call (T *obj,R (*function) (ATs...),ATs... arguments) :obj(obj),function (function),tuplearg (arguments...) {}
+ Call (T *obj,R (T::*function) (ATs...),ATs... arguments) :obj(obj),function (function),tuplearg (arguments...) {}

~Call() {}
bool dispatch (void)
{
- return TupleUnpack<sizeof ...(ATs)>::unpack (this->function, this->tuplearg);
+ return TupleUnpack<sizeof ...(ATs)>::unpack(obj, this->function, this->tuplearg);
}

private:
std::tuple<ATs...> tuplearg;
- R (*function) (ATs...);
+ R (T::*function) (ATs...);

T *obj;
};
@@ -71,8 +69,7 @@ template <typename T, typename R, typename... ATs>
pthread_t NewThread(T *ob, R (T::*mem)(ATs...), ATs... args)
{
pthread_t tid;
- R (*func) (ATs...);
- Call<T,R,ATs...> *task=new Call<T,R,ATs...>(ob,&test,args...);
+ Call<T,R,ATs...> *task=new Call<T,R,ATs...>(ob,mem,args...);

pthread_create(&tid, nullptr, stub<T,R,ATs...>, task) ;

关于c++ - C++ 的通用线程 C 包装器函数,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/16503184/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com