admin管理员组文章数量:1318993
I needed to create a few threads in C++ and wrote this a few years ago. Im not sure why I created the static cast to spawn the task, but I remember it was the only way I could make the thread in a class. Can anyone please help me refresh my foggy brain?
#include <thread>
#include <cstdio>
#include <iostream>
#include "aclass.hpp"
void AClass::staticEntryPoint(void * c)
{
return ((AClass *) c)->AClassThread();
}
void AClass::AClassThread(void)
{
while (!Global::g_terminate_all && !_terminate_me)
{
// thread task here
std::this_thread::sleep_for(std::chrono::milliseconds(10));
}
}
AClass::AClass(void)
{
bool _terminate_me = false;
std::thread txrxthreadObj(staticEntryPoint, this);
txrxthreadObj.detach();
}
AClass::~AClass(void)
{
_terminate_me = true;
}
I needed to create a few threads in C++ and wrote this a few years ago. Im not sure why I created the static cast to spawn the task, but I remember it was the only way I could make the thread in a class. Can anyone please help me refresh my foggy brain?
#include <thread>
#include <cstdio>
#include <iostream>
#include "aclass.hpp"
void AClass::staticEntryPoint(void * c)
{
return ((AClass *) c)->AClassThread();
}
void AClass::AClassThread(void)
{
while (!Global::g_terminate_all && !_terminate_me)
{
// thread task here
std::this_thread::sleep_for(std::chrono::milliseconds(10));
}
}
AClass::AClass(void)
{
bool _terminate_me = false;
std::thread txrxthreadObj(staticEntryPoint, this);
txrxthreadObj.detach();
}
AClass::~AClass(void)
{
_terminate_me = true;
}
Share
Improve this question
asked Jan 19 at 22:42
Richard KlosinskiRichard Klosinski
1211 silver badge8 bronze badges
7
|
Show 2 more comments
1 Answer
Reset to default 1A std::thread
object takes a unary function as argument that it invokes.
A class method needs the object as "implicit" argument.
You, for some reason, decide to pass that as void*
to a static
member function (which is not actually a method and has no instance to work on), and then need to cast it back to the correct type to be able to access members; that's a bit useless to have as a static member function, a freestanding function taking a pointer to your instance would have worked the same but less confusingly. The C-style cast and the fact you're doing this here at all is pretty suspicious – it says "C codebase adopted with minimal changes"; and that's not good here.
You wouldn't solve this problem like that, but simply do this with a capturing lambda, i.e., instead of your whole AClass:staticEntryPoint
method, you'd use
std::thread txrxthreadObj([this](){ this->AClassThread();});
Other than that, this code is not inherently thread save. Multiple threads might be accessing _terminate_me
concurrently.
Totally unsure why you have detach
in there, that seems very questionable, especially since you're only stopping the thread in the destructor of the class. I can't really say whether and how you guarantee that resources used by the thread at that point are still available, but it does reek of being the wrong solution to an ownership problem.
本文标签: cStarting a thread from within a classStack Overflow
版权声明:本文标题:c++ - Starting a thread from within a class - Stack Overflow 内容由网友自发贡献,该文观点仅代表作者本人, 转载请联系作者并注明出处:http://www.betaflare.com/web/1742055414a2418263.html, 本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌抄袭侵权/违法违规的内容,一经查实,本站将立刻删除。
void*
anymore asstd::thread
functions can take pointer that aren't to void .... or it can take any copyable object .. but you didn't update the function and still kept using thevoid*
argument – Ahmed AEK Commented Jan 19 at 22:57_terminate_me
is a class member then you needed to join the thread, not detach it, as after the destructor ends, reading_terminate_me
from the other thread is UB. and will crash your program ... so make the thread a member of the class and join it in the destructor. – Ahmed AEK Commented Jan 19 at 23:00std::thread txrxthreadObj( &AClass::AClassThread, this );
. – dalfaB Commented Jan 19 at 23:03bool
from two threads is UB, the compiler can only check it once at the thread start then not check it anymore ... so_terminate_me
needs to be astd::atomic<bool>
... and a member .... next to thestd::thread
member – Ahmed AEK Commented Jan 19 at 23:10