c++ 11 thread构造函数抛出异常

jack_leiwin 2014-08-15 10:37:09
各位前辈,你们好,我最近使用c++11 thread并行了一个程序,但是thread构造函数在vs2012上抛出了system_error 异常,提示资源不可利用,但是在linux平台上却不会抛出此异常,郁闷
...全文
782 28 打赏 收藏 转发到动态 举报
写回复
用AI写文章
28 条回复
切换为时间正序
请发表友善的回复…
发表回复
cqdjyy01234 2015-01-24
  • 打赏
  • 举报
回复
引用 20 楼 jack_leiwin 的回复:
[quote=引用 11 楼 cqdjyy01234 的回复:] 没有调用join的原因。下面的代码你可以试一下,应该是一样的。之所以会崩溃,是因为thread的析构函数,你可以看看源码。
#include <thread>
#include <iostream>
#include <mutex>

std::mutex cout_mutex;
void foo(){
	std::lock_guard<std::mutex> lock(cout_mutex);
	std::cout << "thread " << std::this_thread::get_id() << "\n";
}

#include <array>
int main(){
	std::array<std::thread, 10> threads;

	for (auto&& t : threads) t = std::thread(foo);
	for (auto&& t : threads) t.join(); // 注掉这一句程序会崩溃

	return 0;
}
如果在创建线程后直接join的话,岂不是得等到创建的线程结束,才能进入下一次循环,进行新线程创建?可是我想要一下子创建10多个线程,多个线程可以并行执行,然后统一join统一退出,如果按照你说的那样,没有多线程的效果啊?[/quote] ??我的代码可不就是这样吗??没让你立刻调用,只要在变量生命周期结束之前调用就可以了。
jack_leiwin 2015-01-24
  • 打赏
  • 举报
回复
引用 27 楼 cqdjyy01234 的回复:
[quote=引用 20 楼 jack_leiwin 的回复:] [quote=引用 11 楼 cqdjyy01234 的回复:] 没有调用join的原因。下面的代码你可以试一下,应该是一样的。之所以会崩溃,是因为thread的析构函数,你可以看看源码。
#include <thread>
#include <iostream>
#include <mutex>

std::mutex cout_mutex;
void foo(){
	std::lock_guard<std::mutex> lock(cout_mutex);
	std::cout << "thread " << std::this_thread::get_id() << "\n";
}

#include <array>
int main(){
	std::array<std::thread, 10> threads;

	for (auto&& t : threads) t = std::thread(foo);
	for (auto&& t : threads) t.join(); // 注掉这一句程序会崩溃

	return 0;
}
如果在创建线程后直接join的话,岂不是得等到创建的线程结束,才能进入下一次循环,进行新线程创建?可是我想要一下子创建10多个线程,多个线程可以并行执行,然后统一join统一退出,如果按照你说的那样,没有多线程的效果啊?[/quote] ??我的代码可不就是这样吗??没让你立刻调用,只要在变量生命周期结束之前调用就可以了。[/quote] I'm sorry, 我错咧。 其实,按照我已有的创建多线程的方式,我又从新写了一个小测试程序,发现是没有问题,小测试程序的taskFunk中只是互斥的访问stdout, 输出线程id,线程数目设很大都没有问题。 目前问题应该很可能是像25楼说的那样,我的taskFunc里面有访问多个线程共享的临界资源变量,但是我通过互斥量和条件变量保证了taskFunc的可重入性了
引用 25 楼 dujie4752041 的回复:
[quote=引用 9 楼 jack_leiwin 的回复:] [quote=引用 5 楼 whoho 的回复:] [quote=引用 3 楼 jack_leiwin 的回复:] [quote=引用 1 楼 whoho 的回复:] 你把函数调用栈打出来?截屏也可以 相应代码附上,不然没人是神仙喔

thread *th=new thread[THTREAD_NUMBER];

for(int i=0;i<THREAD_NUMBER;i++)
{
        th[i]=thread(taskFunc, task);
}

就这段小代码,当THREADD_NUMBER超过10 的时候,就会爆出system_error异常,提示资源不可利用[/quote] 1)Winows进程内的线程数不是10,而是大得多的一个数(你google下) 2)你的这段代码是不是反复调用了?如果是,那么我告诉你,你这里有明显的资源泄漏 可能你反复泄漏了线程句柄,达到上限,所以创建不了新线程 你代码的错误简单地说,就是new出来的那一组线程已经占用资源了,循环内赋了另外一个值,之前分配的被丢失了 [/quote] 没有循环调用,这段代码,在一个是,这是一部分,下一部分就是

for(int i=0;i<THREAD_NUMBER;i++)
{
threadList[i].join();
}
 delete [] threadList;
[/quote] 你们都忽略了一个问题, 他所使用的 “thx[i]=thread( taskfunc , task);” 这个 taskfunc 这个里面是否有不可重入的代码,如果是这样, 一切就好说了。[/quote] 因为我的程序在Linux中跑是没有问题的,创建线程是抛出异常只是在Windows的vs2012中跑才会出现
赵4老师 2015-01-23
  • 打赏
  • 举报
回复
引用 22 楼 jack_leiwin 的回复:
[quote=引用 21 楼 zhao4zhong1 的回复:] 《Windows核心编程》
前辈能够在讲的直接详细一点吗? 这样我看书也能够有目的性[/quote] 印象中里面讲了很多多线程创建和销毁的注意事项。
jack_leiwin 2015-01-23
  • 打赏
  • 举报
回复
引用 21 楼 zhao4zhong1 的回复:
《Windows核心编程》
前辈能够在讲的直接详细一点吗? 这样我看书也能够有目的性
赵4老师 2015-01-23
  • 打赏
  • 举报
回复
《Windows核心编程》
jack_leiwin 2015-01-23
  • 打赏
  • 举报
回复
引用 11 楼 cqdjyy01234 的回复:
没有调用join的原因。下面的代码你可以试一下,应该是一样的。之所以会崩溃,是因为thread的析构函数,你可以看看源码。
#include <thread>
#include <iostream>
#include <mutex>

std::mutex cout_mutex;
void foo(){
	std::lock_guard<std::mutex> lock(cout_mutex);
	std::cout << "thread " << std::this_thread::get_id() << "\n";
}

#include <array>
int main(){
	std::array<std::thread, 10> threads;

	for (auto&& t : threads) t = std::thread(foo);
	for (auto&& t : threads) t.join(); // 注掉这一句程序会崩溃

	return 0;
}
如果在创建线程后直接join的话,岂不是得等到创建的线程结束,才能进入下一次循环,进行新线程创建?可是我想要一下子创建10多个线程,多个线程可以并行执行,然后统一join统一退出,如果按照你说的那样,没有多线程的效果啊?
mujiok2003 2015-01-23
  • 打赏
  • 举报
回复
引用
thread *th = (thread*)mallock( THREAD_NUMBER * sizeof(thread) ); //然后 th[i]=thread( taskfunc , task);
th[i]=thread( taskfunc , task); 这里会调用move assignment(一般先释放th[i]的内部资源, 再move), 因为th[i]没有构造过, 其内部结构式垃圾, 行为就不可知了。
dujie4752041 2015-01-23
  • 打赏
  • 举报
回复
引用 9 楼 jack_leiwin 的回复:
[quote=引用 5 楼 whoho 的回复:] [quote=引用 3 楼 jack_leiwin 的回复:] [quote=引用 1 楼 whoho 的回复:] 你把函数调用栈打出来?截屏也可以 相应代码附上,不然没人是神仙喔

thread *th=new thread[THTREAD_NUMBER];

for(int i=0;i<THREAD_NUMBER;i++)
{
        th[i]=thread(taskFunc, task);
}

就这段小代码,当THREADD_NUMBER超过10 的时候,就会爆出system_error异常,提示资源不可利用[/quote] 1)Winows进程内的线程数不是10,而是大得多的一个数(你google下) 2)你的这段代码是不是反复调用了?如果是,那么我告诉你,你这里有明显的资源泄漏 可能你反复泄漏了线程句柄,达到上限,所以创建不了新线程 你代码的错误简单地说,就是new出来的那一组线程已经占用资源了,循环内赋了另外一个值,之前分配的被丢失了 [/quote] 没有循环调用,这段代码,在一个是,这是一部分,下一部分就是

for(int i=0;i<THREAD_NUMBER;i++)
{
threadList[i].join();
}
 delete [] threadList;
[/quote] 你们都忽略了一个问题, 他所使用的 “thx[i]=thread( taskfunc , task);” 这个 taskfunc 这个里面是否有不可重入的代码,如果是这样, 一切就好说了。
mujiok2003 2015-01-23
  • 打赏
  • 举报
回复
引用 17 楼 jack_leiwin 的回复:
我突然发下一个问题 我的thread数组是这样子的

thread *th = (thread*)mallock( THREAD_NUMBER * sizeof(thread) );
//然后
th[i]=thread( taskfunc , task);

//这个thread数组是不是有问题?

//如果按照下面的来
thread *thx = new thread[THREAD_NUMBER];
thx[i]=thread( taskfunc , task);
//貌似没有什么问题
这两个有什么区别吗? 我用string类也试了一下,如下

//情况一
string *str=new string[100];
str[0]=string("task function");
//情况二
string *strx=(string*)malloc(100*sizeof(string));
strx[0]=string("task function");

//这两者貌似都没有问题诶
不要用malloc,用new []
jack_leiwin 2014-11-19
  • 打赏
  • 举报
回复
我突然发下一个问题 我的thread数组是这样子的

thread *th = (thread*)mallock( THREAD_NUMBER * sizeof(thread) );
//然后
th[i]=thread( taskfunc , task);

//这个thread数组是不是有问题?

//如果按照下面的来
thread *thx = new thread[THREAD_NUMBER];
thx[i]=thread( taskfunc , task);
//貌似没有什么问题
这两个有什么区别吗? 我用string类也试了一下,如下

//情况一
string *str=new string[100];
str[0]=string("task function");
//情况二
string *strx=(string*)malloc(100*sizeof(string));
strx[0]=string("task function");

//这两者貌似都没有问题诶
jack_leiwin 2014-11-19
  • 打赏
  • 举报
回复
引用 18 楼 idzeta 的回复:
[quote=引用 17 楼 jack_leiwin 的回复:] 我突然发下一个问题 我的thread数组是这样子的

thread *th = (thread*)mallock( THREAD_NUMBER * sizeof(thread) );
//然后
th[i]=thread( taskfunc , task);

//这个thread数组是不是有问题?
这和顶楼写的不一样啊……楼主到底是用new的还是只分配了内存而没有构造?如果你跳过thread的构造函数来用,那出错也不奇怪了……
引用 17 楼 jack_leiwin 的回复:
//如果按照下面的来 thread *thx = new thread[THREAD_NUMBER]; thx[i]=thread( taskfunc , task); //貌似没有什么问题
这两个有什么区别吗? 当然有区别了:new除了分配内存外,还要执行构造函数的。[/quote] 还有别的区别吗?因为采用上面的那种方式在linux(Centos)中是没有问题的,在Win7中vs2012中是有问题的
idzeta 2014-11-19
  • 打赏
  • 举报
回复
引用 17 楼 jack_leiwin 的回复:
我突然发下一个问题 我的thread数组是这样子的

thread *th = (thread*)mallock( THREAD_NUMBER * sizeof(thread) );
//然后
th[i]=thread( taskfunc , task);

//这个thread数组是不是有问题?
这和顶楼写的不一样啊……楼主到底是用new的还是只分配了内存而没有构造?如果你跳过thread的构造函数来用,那出错也不奇怪了……
引用 17 楼 jack_leiwin 的回复:
//如果按照下面的来 thread *thx = new thread[THREAD_NUMBER]; thx[i]=thread( taskfunc , task); //貌似没有什么问题
这两个有什么区别吗? 当然有区别了:new除了分配内存外,还要执行构造函数的。
「已注销」 2014-10-16
  • 打赏
  • 举报
回复
引用 15 楼 hlx_beat 的回复:
VS2013 都不完全支持11
但已经支持大部分了
hlx_beat 2014-10-15
  • 打赏
  • 举报
回复
VS2013 都不完全支持11
jack_leiwin 2014-08-18
  • 打赏
  • 举报
回复
引用 13 楼 whoho 的回复:
莫非你用VC链接的是单线程版本的CRT? 请到工程属性页去检查这些参数用了哪个 /MD、/MDd 和/MT、/MTd
用的是/MTd
whoho 2014-08-18
  • 打赏
  • 举报
回复
莫非你用VC链接的是单线程版本的CRT? 请到工程属性页去检查这些参数用了哪个 /MD、/MDd 和/MT、/MTd
jack_leiwin 2014-08-17
  • 打赏
  • 举报
回复
引用 5 楼 whoho 的回复:
[quote=引用 3 楼 jack_leiwin 的回复:] [quote=引用 1 楼 whoho 的回复:] 你把函数调用栈打出来?截屏也可以 相应代码附上,不然没人是神仙喔

thread *th=new thread[THTREAD_NUMBER];

for(int i=0;i<THREAD_NUMBER;i++)
{
        th[i]=thread(taskFunc, task);
}

就这段小代码,当THREADD_NUMBER超过10 的时候,就会爆出system_error异常,提示资源不可利用[/quote] 1)Winows进程内的线程数不是10,而是大得多的一个数(你google下) 2)你的这段代码是不是反复调用了?如果是,那么我告诉你,你这里有明显的资源泄漏 可能你反复泄漏了线程句柄,达到上限,所以创建不了新线程 你代码的错误简单地说,就是new出来的那一组线程已经占用资源了,循环内赋了另外一个值,之前分配的被丢失了 [/quote] 没有循环调用,这段代码,在一个是,这是一部分,下一部分就是

for(int i=0;i<THREAD_NUMBER;i++)
{
threadList[i].join();
}
 delete [] threadList;
jack_leiwin 2014-08-17
  • 打赏
  • 举报
回复
引用 6 楼 whoho 的回复:
你可以保存指针,而不是保存线程对象
thread* th[THTREAD_NUMBER];
 
for(int i=0;i<THREAD_NUMBER;i++)
        th[i] = new thread(taskFunc, task);
酱紫不可以编译通过
whoho 2014-08-17
  • 打赏
  • 举报
回复
你可以保存指针,而不是保存线程对象
thread* th[THTREAD_NUMBER];
 
for(int i=0;i<THREAD_NUMBER;i++)
        th[i] = new thread(taskFunc, task);
whoho 2014-08-17
  • 打赏
  • 举报
回复
引用 3 楼 jack_leiwin 的回复:
[quote=引用 1 楼 whoho 的回复:] 你把函数调用栈打出来?截屏也可以 相应代码附上,不然没人是神仙喔

thread *th=new thread[THTREAD_NUMBER];

for(int i=0;i<THREAD_NUMBER;i++)
{
        th[i]=thread(taskFunc, task);
}

就这段小代码,当THREADD_NUMBER超过10 的时候,就会爆出system_error异常,提示资源不可利用[/quote] 1)Winows进程内的线程数不是10,而是大得多的一个数(你google下) 2)你的这段代码是不是反复调用了?如果是,那么我告诉你,你这里有明显的资源泄漏 可能你反复泄漏了线程句柄,达到上限,所以创建不了新线程 你代码的错误简单地说,就是new出来的那一组线程已经占用资源了,循环内赋了另外一个值,之前分配的被丢失了
加载更多回复(8)

64,651

社区成员

发帖
与我相关
我的任务
社区描述
C++ 语言相关问题讨论,技术干货分享,前沿动态等
c++ 技术论坛(原bbs)
社区管理员
  • C++ 语言社区
  • encoderlee
  • paschen
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
  1. 请不要发布与C++技术无关的贴子
  2. 请不要发布与技术无关的招聘、广告的帖子
  3. 请尽可能的描述清楚你的问题,如果涉及到代码请尽可能的格式化一下

试试用AI创作助手写篇文章吧