pthread 是否可以调用同一个 class 中的 start_routine?
Is it possible for pthread to call a start_routine that is in the same class?
例如
class Foo
{
void assingTask()
{
pthread_t myThread;
int i;
pthread_create(myThread, NULL, task, (void*) i)
}
void * task(void *val)
{
//DO Stuff
}
};
我不断收到 'task' 不是静态函数的错误。我在网上看到的所有内容都提到有一个 find this。这些问题的解决方案远远超出了我的技能水平。谢谢你的帮助。
问题是 pthread_create
是一个 C 函数,而不是 C++ 函数,因此从 C++ 中使用它可能很棘手。第三个参数需要是一个 function 指针,但你试图用一个 method 指针调用它,这不是一回事。
C++ 确实允许将 static 方法指针隐式转换为函数指针,因此您可以用它做任何您想做的事(这就是为什么您会收到错误提示 'task' 不是静态的——因为如果是静态的,它可以转换为函数指针并使用)。通常你然后使用第 4 个参数来保存 "this" 这样你就可以从静态方法
调用非静态方法
class Foo
{
void assingTask()
{
pthread_t myThread;
int i;
pthread_create(&myThread, NULL, start_task, this)
}
static void *start_task(void *this_) {
return static_cast<Foo *>(this_)->task();
}
void * task()
{
//DO Stuff
}
};
上面的代码有一个问题,你 "lose" pthread_t 句柄(不要将它存储在任何可访问的地方),所以你不能加入或脱离线程,但这可能可以通过多种方式修复。
当然可以。将您的数据放入结构中并将其包装在蹦床函数中以跳转到您的 class 函数:
#include <pthread.h>
#include <stdint.h>
class Foo;
// the context passed to trapoline function
struct FooTaskTrampolineCtx {
Foo *obj;
void *val;
};
extern "C" void *FooTaskTrampoline(void *ptr);
struct Foo {
void assingTask() {
pthread_t myThread;
int i;
// note - memory allocated dynamically
struct FooTaskTrampolineCtx *c = new FooTaskTrampolineCtx;
c->obj = this;
c->val = (void*)(uintptr_t)i;
pthread_create(&myThread, NULL, FooTaskTrampoline, c);
}
void * task(void *val) {
//DO Stuff
}
};
extern "C" void FooTaskTrampolineCleanup(void *ptr) {
struct FooTaskTrampolineCtx *c = (struct FooTaskTrampolineCtx *)ptr;
delete c;
}
// trampolines to task method
extern "C" void *FooTaskTrampoline(void *ptr) {
struct FooTaskTrampolineCtx *c = (struct FooTaskTrampolineCtx *)ptr;
void *ret = NULL;
// remember to pick out the trash the PThread(TM) way
pthread_cleanup_push(FooTaskTrampolineCleanup, ptr);
ret = c->obj->task(c->val);
pthread_cleanup_pop(1);
return ret;
}
例如
class Foo
{
void assingTask()
{
pthread_t myThread;
int i;
pthread_create(myThread, NULL, task, (void*) i)
}
void * task(void *val)
{
//DO Stuff
}
};
我不断收到 'task' 不是静态函数的错误。我在网上看到的所有内容都提到有一个 find this。这些问题的解决方案远远超出了我的技能水平。谢谢你的帮助。
问题是 pthread_create
是一个 C 函数,而不是 C++ 函数,因此从 C++ 中使用它可能很棘手。第三个参数需要是一个 function 指针,但你试图用一个 method 指针调用它,这不是一回事。
C++ 确实允许将 static 方法指针隐式转换为函数指针,因此您可以用它做任何您想做的事(这就是为什么您会收到错误提示 'task' 不是静态的——因为如果是静态的,它可以转换为函数指针并使用)。通常你然后使用第 4 个参数来保存 "this" 这样你就可以从静态方法
调用非静态方法class Foo
{
void assingTask()
{
pthread_t myThread;
int i;
pthread_create(&myThread, NULL, start_task, this)
}
static void *start_task(void *this_) {
return static_cast<Foo *>(this_)->task();
}
void * task()
{
//DO Stuff
}
};
上面的代码有一个问题,你 "lose" pthread_t 句柄(不要将它存储在任何可访问的地方),所以你不能加入或脱离线程,但这可能可以通过多种方式修复。
当然可以。将您的数据放入结构中并将其包装在蹦床函数中以跳转到您的 class 函数:
#include <pthread.h>
#include <stdint.h>
class Foo;
// the context passed to trapoline function
struct FooTaskTrampolineCtx {
Foo *obj;
void *val;
};
extern "C" void *FooTaskTrampoline(void *ptr);
struct Foo {
void assingTask() {
pthread_t myThread;
int i;
// note - memory allocated dynamically
struct FooTaskTrampolineCtx *c = new FooTaskTrampolineCtx;
c->obj = this;
c->val = (void*)(uintptr_t)i;
pthread_create(&myThread, NULL, FooTaskTrampoline, c);
}
void * task(void *val) {
//DO Stuff
}
};
extern "C" void FooTaskTrampolineCleanup(void *ptr) {
struct FooTaskTrampolineCtx *c = (struct FooTaskTrampolineCtx *)ptr;
delete c;
}
// trampolines to task method
extern "C" void *FooTaskTrampoline(void *ptr) {
struct FooTaskTrampolineCtx *c = (struct FooTaskTrampolineCtx *)ptr;
void *ret = NULL;
// remember to pick out the trash the PThread(TM) way
pthread_cleanup_push(FooTaskTrampolineCleanup, ptr);
ret = c->obj->task(c->val);
pthread_cleanup_pop(1);
return ret;
}