c – 一种破坏“线程”类的方法
这是我的线程类的骨架:
class MyThread { public: virutal ~MyThread(); // will start thread with svc() as thread entry point void start() = 0; // derive class will specialize what the thread should do virtual void svc() = 0; }; 在代码的某处我创建了一个MyThread的实例,后来我想要销毁它. 破坏线程对象的可接受方法是什么? 注意:我正在寻找平台无关的解决方案. UPD:问题的根源显然是C对象代表线程和OS线程之间没有关系.所以问题是:在对象去除的上下文中,是否有一种可接受的方法可以使线程对象像普通的C对象一样运行,或者它应该被视为一个不寻常的对象(例如,我们应该在抛弃它之前调用join()吗? 解决方法
考虑到你的额外要求发布作为评论Checkers的答复(这是
最简单的方法): 我同意由于各种原因加入DTor是有问题的.但是从那开始,线程对象的生命周期与OS线程对象的生命周期无关. 首先,您需要将线程使用的数据与线程对象本身分开.它们是具有不同生命期要求的不同实体. 一种方法是重新安装数据,并且任何想要访问它的线程都拥有对数据的强引用.这样,任何线程都不会突然陷入虚空,但是一旦没有人接触到数据,数据就会被破坏. 第二,关于线程加入时被破坏的线程对象: 通常,我完全将线程对象的生命周期与OS线程的生命周期分离:销毁线程对象不应该影响线程本身.我看到两种基本方法: >线程句柄对象 – 由线程创建者返回的引用再次计数,可以在不影响OS线程的情况下尽早释放.它将公开诸如Join,IsFinished之类的方法,并且可以提供对线程共享数据的访问. (如果线程对象持有相关的执行状态,则threafFunc本身可以保存对它的引用,从而确保在线程结束之前不会释放实例) > Thin Wrapper – 您只需在OS线程句柄周围创建一个临时文件.您无法轻松保持线程的其他状态,但它可能足以使其工作:在任何地方,您都可以将OS线程句柄转换为线程对象.大多数通信 – 例如告诉线程终止 – 将通过共享数据. 对于您的代码示例,这意味着:将start()与svc()分开 你大致使用这个API(XxxxPtr可能是例如boost :: shared_ptr): class Thread { public: bool IsFinished(); void Join(); bool TryJoin(long timeout); WorkerPtr GetWorker(); static ThreadPtr Start(WorkerPtr worker); // creates the thread }; class Worker { private: virtual void Svc() = 0; friend class Thread; // so thread can run Svc() } Worker可以包含一个ThreadPtr本身,保证在执行Svc()期间存在线程对象.如果允许多个线程处理相同的数据,则必须是线程列表.否则,Thread :: Start必须拒绝已经与线程关联的Worker. 动机:如何处理阻塞的流氓线程? >死锁,你的应用程序挂起.如果您加入析构函数,通常会发生这种情况.>暴力终止线程.这可能是应用程序的暴力终止.>让线程在其自己的数据上运行完成 – 您可以通知用户,谁可以安全地保存&出口.或者你只是让流氓线程在它自己的数据副本上跳舞(不再由主线程引用)直到它完成. (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |