本文介绍了终止工人的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧! 问题描述 我有一个函数,它启动了多个工作线程。每个工作线程被一个对象封装,并且该对象的析构函数会尝试 join 线程,即调用 if(thrd_.joinable )thrd_.join(); 。但是,事先不知道每个工人将要做多少工作。管理功能使用互斥量和条件变量将工作单元分配给线程。如果没有更多的工作要做,在保持互斥锁期间设置某个标志,然后通知在条件变量上阻塞的所有线程,以便他们醒来,注意到改变的标志,并关闭。 我想这个关闭工作,即使在主线程中有一个异常。在Java中,我将使用 finally 子句始终设置标志并在工作处理循环结束时通知线程。由于 C ++没有 finally ,我写了自己的替换: class FinallyGuard { private: std :: function< void()> F_; public: FinallyGuard(std :: function< void()> f):f_(f){} 〜FinallyGuard(){f_ } }; void Manager :: manageWork(unsigned NumWorkers){ //顺序问题:析构函数以相反的顺序调用,并将 // 1.释放互斥锁,以便工作可以继续 // 2.使用finally workalike解除所有线程 // 3.销毁工作线程并加入线程 std :: forward_list< Worker>工人; FinallyGuard signalEndGuard([this] { std :: unique_lock< std :: mutex> lk(mtx_); done_ = true; beginWork_.notify_all(); }); std :: unique_lock< std :: mutex> lk(mtx_); for(unsigned i = 0; i!= numWorkers; ++ i) workers.emplace_front(this); while(haveMoreWork()){ // ... } } 但我清楚地从这里的其他语言的概念。 是否有更多的C ++方式来实现这一点?解决方案将需要执行一些代码,从一个方法的正常返回和抛出异常的情况,或提供一些更好的机制解决方案在C ++中存在一个try finally等价类型,尽管不是在核心语言。它被称为ScopeGuard由Andrej Alexandrescu创造的一个摇滚明星的C ++字段。在这里,他介绍了C ++和Beyond会议2012的新版本 http://channel9.msdn.com/Shows/Going+Deep/C-and-Beyond-2012-Andrei-Alexandrescu-Systematic-Error-Handling-in-C 更重要的是代码: https://gist.github.com/KindDragon/4650442 您的例子几乎是一样的。你可能应该把它称为ScopeGuard或使用Alexandrescus代码(你应该放在一个库或常用的包括,它常常使用)如果你想让其他C ++程序员明白你的意思。 C ++程序员使用RAII的一切,在我的脑海里表示意图是很重要的,这是很好地完成的 SCOPE_EXIT { std :: unique_lock< std :: mutex> lk(mtx_); done_ = true; beginWork_.notify_all(); }; $ b 工作ScopeGuard被认为是好的风格,通过代码审查只是罚款。它是公共领域,如果你想使用它的商业。 I've got a function which starts a number of worker threads. Each worker thread is encapsulated by an object, and the destructor of that object will try to join the thread, i.e calls if (thrd_.joinable()) thrd_.join();. But it is unknown a priori how much work each worker will have to perform. the managing function assigns work units to the threads using a mutex and a condition variable. If there is no more work to do, a certain flag is set while the mutex is being held, and then all threads blocked on the condition variable are notified so they wake up, notice the changed flag, and shut down.I want this shutdown to work even if there is an exception in the main thread. In Java I'd use a finally clause to always set the flag and notify threads at the end of the work processing loop. As C++ doesn't have finally, I wrote my own replacement:class FinallyGuard {private: std::function<void()> f_;public: FinallyGuard(std::function<void()> f) : f_(f) { } ~FinallyGuard() { f_(); }};void Manager::manageWork(unsigned NumWorkers) { // Order matters: destructors are called in reverse order and will // 1. release the mutex lock so that workers can proceed // 2. unblock all threads using the finally workalike // 3. destroy the workers and join their threads std::forward_list<Worker> workers; FinallyGuard signalEndGuard([this] { std::unique_lock<std::mutex> lk(mtx_); done_ = true; beginWork_.notify_all(); }); std::unique_lock<std::mutex> lk(mtx_); for (unsigned i = 0; i != numWorkers; ++i) workers.emplace_front(this); while (haveMoreWork()) { // … }}But I'm clearly thinking in concepts from other languages here. Is there a more C++-like way to achieve this? A solution would either need to execute some code both for normal return from a method and for the case where an exception is thrown, or provide some better mechanism to wake up workers instead of the flag and condition variable combination. 解决方案 A try finally equivalent does exist in C++, although not in the core language. It is called a ScopeGuard origionally created by Andrej Alexandrescu one of the "rock stars" of the C++ field. Here he presents the new version at C++ and Beyond conference 2012 http://channel9.msdn.com/Shows/Going+Deep/C-and-Beyond-2012-Andrei-Alexandrescu-Systematic-Error-Handling-in-Cand more importantly here is the code:https://gist.github.com/KindDragon/4650442Your example does pretty much the same thing. You probably should call it a ScopeGuard or use Alexandrescus code (which you should probably put in a library or common include, its used often) if you want other C++ programmers to understand what you mean. C++ Programmers use RAII for everything, in my mind its important to express intent which is done quite nicely by SCOPE_EXIT { std::unique_lock<std::mutex> lk(mtx_); done_ = true; beginWork_.notify_all();};in your case.Where I work ScopeGuard is considered good style and passes code review just fine. It is also public domain in case you want to use it commercially. 这篇关于终止工人的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!
10-28 05:34