Suppose you have the following:
假设您拥有以下内容:
Test.h
Test.h
class Test {
public:
Test();
// Other member variables
void createThread();
}
Test.cpp
Test.cpp
void* threadRunnable(void* arg) {
// Uses Test class member variables
}
Test::Test(){
//
}
void Test::createThread() {
pthread_create(..,threadRunnable,..);
}
How would the function threadRunnable
passed into pthread_create
be able to access member variables without instantiating an object? Or is this not possible.
传入pthread_create的函数threadRunnable如何在不实例化对象的情况下访问成员变量?或者这是不可能的。
Things I've tried:
我试过的东西:
- Singleton with a reference to the class (don't think this works as you still need an object first)
- Making the function
threadRunnable
a member or friend
function
Not sure what else can be done
不知道还能做些什么
更多回答
Unrelated: Why use the platform specific C library pthread
instead of the standard C++ std::thread
or std::jthread
?
无关:为什么要使用特定于平台的C库pTHREAD而不是标准的C++STD::THREAD或STD::JTHREAD?
What Ted said, and use lambda expressions to pass parameters to your thread functions. For C++20 use std::jthread for older versions use std::thread. And if you have a lambda expression you can pass it in as constructor argument of your thread. If you want a thread to calculate something and return the answer later use std::async and you can use a lambda expression with a return value
并使用lambda表达式将参数传递给线程函数。对于C++20,请使用std::j线程;对于较老的版本,请使用std::Three。如果您有一个lambda表达式,您可以将其作为线程的构造函数参数传递。如果您希望线程计算某些内容并在以后返回结果,请使用std::Async,您可以使用带有返回值的lambda表达式
优秀答案推荐
You'd need to supply the pointer to threadRunnable
to pthread_create
and also a pointer to this
. Then cast arg
to a Test*
. I'm using NULL
and a C style cast from void*
to Test*
instead of nullptr
and a static_cast
which will work in pre C++11:
你需要向pthread_create提供指向threadRunnable的指针,同时也提供指向this的指针。然后将arg转换为Test*。我使用了NULL和一个C风格的从void* 到Test* 的转换,而不是nullptr和一个static_cast,这将在C++11之前的版本中工作:
#include <pthread.h>
#include <iostream>
class Test {
public:
~Test() {
pthread_join(th, NULL);
}
void createThread();
private:
friend void* threadRunnable(void*);
pthread_t th;
int x;
};
void* threadRunnable(void* arg) { // <-----------+
Test& tst = *((Test*)(arg)); // *this |
// Uses Test class member variables // |
tst.x = 10; // |
std::cout << tst.x << '\n'; // |
return NULL; // |
} // |
// |
void Test::createThread() { // |
pthread_create(&th, NULL, &threadRunnable, this);
}
int main() {
Test tst;
tst.createThread();
}
A somewhat cleaner way that was often used before C++11 was to make threadRunnable
a member function and to use a static
proxy function with phtread_create
:
在C++11之前经常使用的一种比较简洁的方法是使threadRunnable成为成员函数,并使用带有phtread_create的静态代理函数:
#include <pthread.h>
#include <iostream>
class Test {
public:
~Test() {
pthread_join(th, NULL);
}
void createThread();
private:
static void* runnableProxy(void*);
void threadRunnable();
pthread_t th;
int x;
};
void* Test::runnableProxy(void* instance) {
((Test*)instance)->threadRunnable();
return NULL;
}
void Test::threadRunnable() {
// Uses Test class member variables
x = 10;
std::cout << x << '\n';
}
void Test::createThread() {
pthread_create(&th, NULL, &Test::runnableProxy, this);
}
int main() {
Test tst;
tst.createThread();
}
In modern C++ you'd use std::thread
or std::jthread
instead and then there's no need for a proxy function:
在现代C++中,您可以改用std::Thress或std::JThline,这样就不需要代理函数了:
Example:
示例:
#include <iostream>
#include <thread>
class Test {
public:
void createThread();
private:
void threadRunnable();
std::jthread th;
int x;
};
void Test::threadRunnable() {
// Uses Test class member variables
x = 10;
std::cout << x << '\n';
}
void Test::createThread() {
th = std::jthread(&Test::threadRunnable, this);
}
int main() {
Test tst;
tst.createThread();
}
更多回答
Would you be able to explain how the solution with pthread may work?
你能解释一下pthread的解决方案是如何工作的吗?
@jeff I have two pthread
based solutions in the answer. The first one looks very similar to your code. Did you manage to get it working? If you did, but don't understand why, please ask about the part you want me to clarify further.
@Jeff我在答案中有两个基于pline的解决方案。第一个看起来与您的代码非常相似。你设法让它工作了吗?如果你有,但不明白为什么,请询问你想让我进一步澄清的部分。
我是一名优秀的程序员,十分优秀!