C++静态类成员引用 self
我很好奇这是否是我可以做的事情:
using namespace tthread;
class E_thread {
static std::list<E_thread*> all_threads;
thread th;
E_messageQueue queue;
public:
E_thread(void (*threadFunction)(void *), void * threadFuncArg) {
all_threads.push_back(this);
th = thread(threadFunction,threadFuncArg);
}
~E_thread() {
queue.push_terminate_thread_message();
th.join();
all_threads.remove(this);
}
};
我的目的是让任何线程都可以轻松地生成新线程或向另一个线程发送消息,并且线程列表也能够自行清理。据我了解,我可以将 all_threads
替换为全局 std::list
,如果我愿意的话,它可以达到相同的目的,但不是这是一种获得这种“全球性”的更干净的方法吗?
对此有点不安的是,我没有强制我的新线程有一个消息读取循环,以便能够处理终止消息。
I'm curious as to whether this is something that I can do:
using namespace tthread;
class E_thread {
static std::list<E_thread*> all_threads;
thread th;
E_messageQueue queue;
public:
E_thread(void (*threadFunction)(void *), void * threadFuncArg) {
all_threads.push_back(this);
th = thread(threadFunction,threadFuncArg);
}
~E_thread() {
queue.push_terminate_thread_message();
th.join();
all_threads.remove(this);
}
};
My intention is to make it easy for any thread to spawn new threads or to send messages to another thread, and the thread list also is capable of cleaning up after itself. As far as I understand it I could replace all_threads
with a global std::list<E_thread*>
which serves the same purpose if I wanted to, but isn't this a cleaner method of getting that sort of "globalness"?
What's a little uneasy about this is that I haven't forced my new threads to have a message reading loop, to be able to handle the terminate message.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
大多数情况下,这很好。您需要使用某种互斥体来保护对
all_threads
的访问(读取或修改两者)。另外,如果您在程序运行过程中经常销毁线程,那么最好使用::std::set
。另外,我对是否拥有任何类型的全局变量有些疑问。我认为如果您有一个“线程管理器”对象,您在创建线程时传递了一个“线程管理器”对象,或者可能有一个线程工厂来跟踪它创建的所有线程,那么它会更干净。
全局变量使程序更难测试,并使它们更脆弱并且以后修改的能力更差。
This is fine, mostly. You need to protect access (reading or modifying both) to
all_threads
with a mutex of some sort. Also, you would be better served to use a::std::set
if you destroy threads often during the course of your program.Also, I sort of question having global variables of any kind. I think it would be cleaner if you had a 'thread manager' object that you passed in what you created a thread, or maybe a thread factory that kept track of all the threads it created.
Global variables make programs much harder to test, and make them more brittle and less capable of being modified later.
如果多个线程尝试加入同一个线程,某些操作系统上的未定义行为
all_threads
需要受到保护通过push_back
、remove
的互斥体以及可能尝试迭代它的任何其他读取器all_threads
的其他线程可能尝试对th
执行某些操作,您可能需要在互斥锁保护块中包含对th
的修改在其分配之前或期间this有串行化线程破坏的倾向,因为
push_terminate_thread_message
被发送到单个线程,然后join
完成。通常最好先发送所有终止消息,然后再执行所有连接
。对我来说,线程如何了解队列并不明显,尽管
threadFuncArg
在某些有限的情况下可能会被滥用Omnifarious 关于适当线程池的建议更具吸引力。
undefined behaviour on some OS if multiple threads attempt to join the same thread
all_threads
needs to be protected by a mutex for thepush_back
,remove
, and any other reader that may try to iterate over itth
in the mutex-protected block if other threads iteratingall_threads
may try to do something toth
before or during its assignmentthis has a tendency to serialise thread destruction, as
push_terminate_thread_message
is sent to a single thread, then ajoin
is done. It's generally better to send all the termination messages then do all thejoins
.it's not obvious to me how the threads are supposed to know about the queues, though the
threadFuncArg
might be abused for this in some limited circumstancesOmnifarious's suggestion of a proper thread pool is much more appealing.