通知线程退出
Notifying threads to exit
这是一个线程池的简单(可能是幼稚的)实现。
我想知道,鉴于下面的方法,是否有一种很好的方法来主动通知线程池线程退出,而不必在每次超时后检查布尔mStopped
。
我知道有更好的方法来实现线程池 - 但我仍然有兴趣看看下面的代码是否可以在不从根本上改变它的情况下得到改进。
我很高兴听到一般建议...不一定修复下面的代码...问题实际上是关于线程上的信号/等待,线程池只是为了提供一些上下文。
我使用的是 gcc 4.4.6(所以下面的一些语法有点过时了),并且代码是用 g++ --std=c++0x main.cc -pthread
编译
#include <vector>
#include <mutex>
#include <thread>
#include <deque>
#include <condition_variable>
#include <functional>
using namespace std;
struct ThreadPool;
struct Worker {
ThreadPool& mThreadPool;
Worker(ThreadPool& threadPool) : mThreadPool(threadPool) {}
void operator()();
};
struct ThreadPool {
vector<thread> mWorkers;
deque<function<void()>> mTasks;
bool mStopped; // not atomic
mutex mMutex;
condition_variable mCond;
ThreadPool() : mStopped(false) {
for (size_t i = 0; i < 5; i++)
mWorkers.push_back(thread(Worker(*this)));
}
~ThreadPool() { stop(); }
void stop() {
if (!mStopped) {
mStopped = true;
for (auto it = mWorkers.begin(); it != mWorkers.end(); ++it)
if (it->joinable()) it->join();
}
}
bool canBreakFromWait() const { return !mTasks.empty(); }
void enqueue(function<void()> f) {
if (mStopped) return;
unique_lock<mutex> lck(mMutex);
mTasks.push_back(f);
mCond.notify_one();
}
};
void Worker::operator()() {
while (true) {
unique_lock<mutex> lck(mThreadPool.mMutex);
mThreadPool.mCond.wait_for(lck, chrono::seconds(1), bind(&ThreadPool::canBreakFromWait, &mThreadPool));
if (mThreadPool.mStopped) break;
auto task = mThreadPool.mTasks.front();
mThreadPool.mTasks.pop_front();
lck.unlock();
task();
}
}
void doWork(int data) {}
int main() {
ThreadPool threadPool;
for (auto i = 0; i < 50; i++)
threadPool.enqueue(bind(doWork, i));
threadPool.stop();
}
两条评论。
首先,由于mStopped
在一个线程中被修改,并在其他线程中访问,对它的所有访问都必须同步。 就目前而言,您的程序尚未定义行为。 这在实践中是否会成为问题,我不知道;先验地,编译器可以stop
推断出没有其他人线程访问变量,并且未在函数返回后调用stop
线程,依此类推禁止分配。
第二个是,如果我有工作列表,我已经通常发现创建一个特殊的工作是最简单的终止线程。 标准线程似乎没有一个thread_exit
函数,但这可以很容易地通过让作业返回布尔值或使用异常。然后,stop
函数锁定互斥锁,清空队列,然后将这些特殊终止作业之一插入队列对于每个线程。
相关文章:
- std::async 如果线程是从 DLL 创建的,则会阻止进程退出?
- 在线程退出之前,线程分配的内存块是否与线程本身具有相同的相关性?
- STD ::线程不会退出
- C++线程退出循环条件
- gdb 中的线程 0x7fffc57fa700 (LWP 31671) 退出] 是什么意思?
- 如何使用工作线程正确退出Qt应用程序
- Boost.Asio:由于线程退出或应用程序请求,I/O 操作已中止
- 当子线程退出时,如何通知父线程
- 线程已退出,代码为 1:Join() 和 Detach()
- 安全地退出程序 Win32 C++从分离的 std::线程
- 在另一个线程正在运行的情况下退出应用程序时出错
- C++提升线程组.interrupt_all()导致主线程也退出
- 确定线程是否已退出
- 在退出应用程序时安全退出Qt线程
- c++允许后台线程在退出应用程序之前完成
- 如果线程在调用pthread_join之前退出,该怎么办
- JNI - Java 在本机线程完成执行之前退出
- 线程退出时通知Waiters
- 多线程Qt应用程序在退出时不会停止
- 如何以线程安全的方式退出 C++03 中的程序