C++11中的线程处理
Threads handling in C++ 11
我有一个基类,它管理线程函数和派生函数,可以在该基类的帮助下设置其函数并发运行。但在我模拟这些功能的快速启动/停止的测试中,我的程序崩溃了。似乎问题出在互斥体上,但我可能错了。问题出在哪里?
class ThreadedBase
{
public:
ThreadedBase(){}
virtual ~ThreadedBase() {
for (int i = 0; i < m_threadedTasks.size(); ++i) {
*m_threadedTasks[i]->run = false;
m_threadedTasks[i]->thread->join();
}
while (m_threadedTasks.size()) {
m_threadedTasks.erase(m_threadedTasks.begin());
}
}
void addTask(std::function<void()> f) {
static int i = 0;
m_threadedTasks.insert({ i++, new ThreadedTask(f)});
}
void startN(int n) {
std::lock_guard<std::mutex> lock(m_threadedTasks[n]->mtx);
std::cout << "StartNn";
if (*m_threadedTasks[n]->run == true) return;
*m_threadedTasks[n]->run = true;
m_threadedTasks[n]->thread = new std::thread((std::mem_fn(&ThreadedBase::run)), this, n);
}
void stopN(int n) {
std::lock_guard<std::mutex> lock(m_threadedTasks[n]->mtx);
std::cout << "StopNn";
*m_threadedTasks[n]->run = false;
}
private:
struct ThreadedTask
{
ThreadedTask(std::function<void()> f) : function(f), thread(nullptr), run(new bool(false)) {}
~ThreadedTask() {
thread->join();
delete thread;
delete run;
}
std::function<void()> function;
std::thread *thread;
mutable std::mutex mtx;
bool *run;
};
std::unordered_map<int, ThreadedTask*> m_threadedTasks;
void run(int n) {
while (*m_threadedTasks[n]->run) {
std::lock_guard<std::mutex> lock(m_threadedTasks[n]->mtx);
m_threadedTasks[n]->function();
std::cout << "yet another loopn";
}
// todo: erase if needed
std::lock_guard<std::mutex> lock(m_threadedTasks[n]->mtx);
*m_threadedTasks[n]->run = false;
delete m_threadedTasks[n]->thread;
m_threadedTasks[n]->thread = nullptr;
}
};
class Test : public ThreadedBase
{
public:
Test() : ThreadedBase() {
addTask(std::bind(std::mem_fn(&Test::threadedBlock1), this));
addTask(std::bind(std::mem_fn(&Test::threadedBlock2), this));
};
void threadedBlock1() {
std::this_thread::sleep_for(std::chrono::milliseconds(200));
std::cout << "Task1 finished ";
}
void threadedBlock2() {
std::this_thread::sleep_for(std::chrono::milliseconds(200));
std::cout << "Task2 finished ";
}
~Test() { std::cout << "Deletingn"; }
void startN(int n) {
ThreadedBase::startN(n);
}
void stopN(int n) {
ThreadedBase::stopN(n);
}
};
int main()
{
Test *t = new Test();
srand(time(NULL));
while (true) {
(0 + rand() % 2 == 0) ? t->startN(0) : t->stopN(0);
}
std::this_thread::sleep_for(std::chrono::seconds(100));
return 0;
}
感谢Joachim Pileborg,我已经完成了这段代码。现在它如下:
class ThreadedBase
{
public:
ThreadedBase(){}
virtual ~ThreadedBase() {
for (int i = 0; i < m_threadedTasks.size(); ++i) {
m_threadedTasks[i]->run = false;
m_threadedTasks[i]->thread.join();
}
while (m_threadedTasks.size()) {
m_threadedTasks.erase(m_threadedTasks.begin());
}
}
void addTask(std::function<void()> f) {
static int i = 0;
m_threadedTasks.insert({ i++, new ThreadedTask(f) });
}
void startN(int n) {
std::lock_guard<std::mutex> lock(m_threadedTasks[n]->mtx);
if (m_threadedTasks[n]->run == true) return;
m_threadedTasks[n]->run = true;
m_threadedTasks[n]->thread = std::thread(&ThreadedBase::run, this, n);
}
void stopN(int n) {
m_threadedTasks[n]->run = false;
if (m_threadedTasks[n]->thread.joinable())
m_threadedTasks[n]->thread.join();
}
private:
struct ThreadedTask
{
ThreadedTask(std::function<void()> f) : function(f), thread(), mtx(), run(false) {}
~ThreadedTask() {
thread.join();
}
std::function<void()> function;
std::thread thread;
mutable std::mutex mtx;
bool run;
};
std::unordered_map<int, ThreadedTask*> m_threadedTasks;
void run(int n) {
while (m_threadedTasks[n]->run) {
std::lock_guard<std::mutex> lock(m_threadedTasks[n]->mtx);
m_threadedTasks[n]->function();
std::cout << "yet another loopn";
}
// todo: erase if needed
m_threadedTasks[n]->run = false;
}
};
class Test : public ThreadedBase
{
public:
Test() : ThreadedBase() {
addTask(std::bind(&Test::threadedBlock1, this));
addTask(std::bind(&Test::threadedBlock2, this));
};
void threadedBlock1() {
std::this_thread::sleep_for(std::chrono::milliseconds(5));
std::cout << "Task1 finished ";
}
void threadedBlock2() {
std::this_thread::sleep_for(std::chrono::milliseconds(5));
std::cout << "Task2 finished ";
}
~Test() { std::cout << "Deletingn"; }
void startN(int n) {
ThreadedBase::startN(n);
}
void stopN(int n) {
ThreadedBase::stopN(n);
}
};
int main()
{
Test *t = new Test();
srand(time(NULL));
while (true) {
(0 + rand() % 2 == 0) ? t->startN(0) : t->stopN(0);
}
std::this_thread::sleep_for(std::chrono::seconds(100));
return 0;
}
相关文章:
- 用于矢量处理的多个线程
- C++:处理线程本地对象销毁
- 通过安装信号处理程序关闭多线程应用程序
- 将更高的优先级设置为 boost::asio 线程处理进程
- 处理影响跨不同线程共享对象的定时回调的最佳方法是什么?
- 在线程函数中处理数据向量时进行线程竞速
- 如何在c++多线程中匹配处理时间和接收时间
- 线程和 GUI 处理
- C++ 使用 2 个容器进行线程处理
- asio::io_service 具有多个线程的优先级队列处理
- 无法在sfml中处理线程
- 在处理线程时,处理错误的正确方法是什么
- 如何处理线程
- 提升线程 - 安全/有保证的处理线程中断的方式
- 您应该如何处理线程中的文件打开错误而不取消
- 如何处理线程函数中的重复代码
- GUI应用程序C++中的事件处理线程
- c++ Win32数据处理线程
- 在差异处理线程之间发送信号
- 如何在visual c++中使用TSL汇编指令处理线程