合肥网站建设需要多少钱,南阳做玉器网站,浙江建设厅网站怎么进不去,wordpress postgresql多线程场景中的栈内存异常
在子线程中尝试使用当前函数的资源#xff0c;是非常危险的#xff0c;但是C支持这么做。因此C这么做可能会造成栈内存异常。
正常代码
#include iostream
#include thread
#include windows.h// 线程函数#xff0c;用…多线程场景中的栈内存异常
在子线程中尝试使用当前函数的资源是非常危险的但是C支持这么做。因此C这么做可能会造成栈内存异常。
正常代码
#include iostream
#include thread
#include windows.h// 线程函数用于执行具体的任务
void fun(int param)
{std::cout __FUNCTION__ param: param std::endl;Sleep(3000);param 1;std::cout __FUNCTION__ param: param std::endl;
}// 线程函数用于执行具体的任务
void threadFunction() {// 在这里执行线程的具体任务int num 2;//在函数中还启动了一个线程std::thread funThread([num](){fun(num);});funThread.detach();
}int main() {const int numThreads 3;std::thread threads[numThreads];// 创建并启动多个线程for (int i 0; i numThreads; i) {threads[i] std::thread(threadFunction);}//等待所有线程执行完毕for (int i 0; i numThreads; i) {threads[i].join();}Sleep(1000);std::cout All threads have completed. std::endl;return 0;
}上述是一个正常的多线程代码。
异常代码
但是如果将其中多线程传参设置为引用传递可能就会造成内存泄露了如下所示
#include iostream
#include thread
#include windows.h// 线程函数用于执行具体的任务
void fun(int param)//传参修改为引用传递
{std::cout __FUNCTION__ param: param std::endl;Sleep(3000);param 1;std::cout __FUNCTION__ param: param std::endl;
}// 线程函数用于执行具体的任务
void threadFunction() {// 在这里执行线程的具体任务int num 2;//在函数中还启动了一个线程传参为引用std::thread funThread([num](){fun(num);});funThread.detach();
}int main() {const int numThreads 3;std::thread threads[numThreads];// 创建并启动多个线程for (int i 0; i numThreads; i) {threads[i] std::thread(threadFunction);}//等待所有线程执行完毕for (int i 0; i numThreads; i) {threads[i].join();}Sleep(1000);std::cout All threads have completed. std::endl;return 0;
}编译成功但是运行失败。 运行结果 上面std::thread funThread(num{fun(num);});采用引用传递并且void fun(int param)中也采用引用入参的形式。此时可能就会产生内存泄露。
因为传入参数num是一个局部参数我们在fun中修改或读取param时可能num已经被释放掉了这时候修改或者读取param就会发生内存错误其实这里是栈内存异常。这是非常危险的因为栈内存可能会造成无法估量的问题。
优化代码
当然我们用引用传递的好处是可以避免临时变量的产生但变量是复杂对象时还是可以很大程度减少内存消耗。虽然不能用引用但是我们可以使用std::move来实现变量所有权的转移也可以减少临时变量的拷贝。
#include iostream
#include thread
#include windows.h// 线程函数用于执行具体的任务
void fun(int param)//右值传参
{std::cout __FUNCTION__ param: param std::endl;Sleep(3000);param 1;std::cout __FUNCTION__ param: param std::endl;
}// 线程函数用于执行具体的任务
void threadFunction() {// 在这里执行线程的具体任务int num 2;//在函数中还启动了一个线程std::thread funThread(fun, std::move(num));//使用move传入右值funThread.detach();
}int main() {const int numThreads 3;std::thread threads[numThreads];// 创建并启动多个线程for (int i 0; i numThreads; i) {threads[i] std::thread(threadFunction);}//等待所有线程执行完毕for (int i 0; i numThreads; i) {threads[i].join();}Sleep(1000);std::cout All threads have completed. std::endl;return 0;
}