WaitForMultipleObjects返回0xffffffff
DWORD ret;
const int THREAD_NUM = ;
HANDLE handle[THREAD_NUM]; for (int i = ; i < THREAD_NUM; i++)
handle[i] = (HANDLE)_beginthreadex(NULL, , CthreadFun, NULL, , NULL);
ret = WaitForMultipleObjects(THREAD_NUM, handle, TRUE, INFINITE);
如上写了个使用_beginthreadex的例子,发现当THREAD_NUM为100时,WaitForMultipleObjects返回的是0xffffffff。
除了什么错误呢,于是使用GetLastError()获取错误号:87,使用vs工具中的错误查找,查找对应的错误信息是"参数错误"。这是什么原因呢?
如果把THREAD_NUM改小后,就没有这个错误了,为什么呢?
假设:
1)WaitForMultipleObjects对参数ncount有大小要求?
2)系统可开的线程个数有限制?
3)线程太多,占用的内存资源多?
使用排除法进行分析:
关于3),_beginthreadex的第二个参数表示堆栈大小,以字节为单位,0默认1M。 100个线程才100M,况且查看内存使用量,没有太多呀!
关于2),msdn原文:
“The number of threads a process can create is limited by the available virtual memory. By default, every thread has one megabyte of stack space. Therefore, you can create at most 2,028 threads. If you reduce the default stack size, you can create more threads. However, your application will have better performance if you create one thread per processor and build queues of requests for which the application maintains the context information. A thread would process all requests in a queue before processing requests in the next queue.”
参考文章:http://www.cnblogs.com/lancidie/archive/2011/12/15/2289337.html 理论上2048个线程数限制。可以通过改小栈的大小增加,默认虽然实际可能达不到2048,但是100个应该可以吧?
并且,如果是2,3的问题,那么在_beginthreadex时应该失败的呀,检查句柄数组handle, 均分配成功,因此排除2,3。
最后关于1)WaitForMultipleObjects的参数范围,参考msdn原文:
DWORD WINAPI WaitForMultipleObjects(
_In_ DWORD nCount,
_In_ const HANDLE *lpHandles,
_In_ BOOL bWaitAll,
_In_ DWORD dwMilliseconds
);Parameters
- nCount [in]
The number of object handles in the array pointed to by lpHandles. The maximum number of object handles is MAXIMUM_WAIT_OBJECTS. This parameter cannot be zero.
- lpHandles [in]
An array of object handles. For a list of the object types whose handles can be specified, see the following Remarks section. The array can contain handles to objects of different types. It may not contain multiple copies of the same handle.
If one of these handles is closed while the wait is still pending, the function's behavior is undefined.
The handles must have the SYNCHRONIZE access right. For more information, see Standard Access Rights.
- bWaitAll [in]
If this parameter is TRUE, the function returns when the state of all objects in the lpHandles array is signaled. If FALSE, the function returns when the state of any one of the objects is set to signaled. In the latter case, the return value indicates the object whose state caused the function to return.
- dwMilliseconds [in]
The time-out interval, in milliseconds. If a nonzero value is specified, the function waits until the specified objects are signaled or the interval elapses. If dwMilliseconds is zero, the function does not enter a wait state if the specified objects are not signaled; it always returns immediately. If dwMilliseconds is INFINITE, the function will return only when the specified objects are signaled.
Return value
If the function succeeds, the return value indicates the event that caused the function to return. It can be one of the following values. (Note that WAIT_OBJECT_0 is defined as 0 and WAIT_ABANDONED_0 is defined as 0x00000080L.)
Return code/value Description
- WAIT_OBJECT_0 to (WAIT_OBJECT_0 + nCount– 1)
If bWaitAll is TRUE, the return value indicates that the state of all specified objects is signaled.
If bWaitAll is FALSE, the return value minus WAIT_OBJECT_0 indicates the lpHandles array index of the object that satisfied the wait. If more than one object became signaled during the call, this is the array index of the signaled object with the smallest index value of all the signaled objects.
- WAIT_ABANDONED_0 to (WAIT_ABANDONED_0 + nCount– 1)
If bWaitAll is TRUE, the return value indicates that the state of all specified objects is signaled and at least one of the objects is an abandoned mutex object.
If bWaitAll is FALSE, the return value minus WAIT_ABANDONED_0 indicates the lpHandles array index of an abandoned mutex object that satisfied the wait. Ownership of the mutex object is granted to the calling thread, and the mutex is set to nonsignaled.
If a mutex was protecting persistent state information, you should check it for consistency.
- WAIT_TIMEOUT
- 0x00000102L
The time-out interval elapsed and the conditions specified by the bWaitAll parameter are not satisfied.
- WAIT_FAILED
- (DWORD)0xFFFFFFFF
The function has failed. To get extended error information, call GetLastError
其中MAXIMUM_WAIT_OBJECTS的值为.这就可以解释了错误号87的问题了。其实解决问题时,绕了个弯,87就是参数错误的意思,当然要首先从出错的函数参数方面找原因,因为自己主观首先臆测了参数范围无限制,导致了浪费时间。
注意以后解决问题要严谨,不可自我感觉,必须有凭有据。
WaitForMultipleObjects返回0xffffffff的更多相关文章
- WaitForMultipleObjects返回失败原因之一
上网搜了下 关于 WaitForMultipleObjects等待多个线程退出的状态失败的情况,也有人遇到类似的情况. 一次项目中我也遇到这么个情况.项目中创建线程都是用的 _beginthread ...
- delphi 多线程3
多线程程序设计 我们知道,win95或winNT都是“多线程”的操作系统,在DELPHI .中,我们可以充分利用这一特性,编写出“多线程”的应用程序. 对以往在DOS或16位windows下写程序的 ...
- Delphi多线程详解
(整理自网络) Delphi多线程处理 1-1多线程的基本概念 WIN 98/NT/2000/XP 是个多任务操作系统,也就是:一个进程可以划分为多个线程,每个线程轮流占用CPU 运行时间和资源,或者 ...
- 整数压缩编码 ZigZag
在分析Avro源码时,发现Avro为了对int.long类型数据压缩,采用Protocol Buffers的ZigZag编码(Thrift也采用了ZigZag来压缩整数). 1. 补码编码 为了便于后 ...
- SQLLocalDB 11.0持续报错,这是泥马德什么问题啊!!!
Windows API 调用 WaitForMultipleObjects 返回了错误代码: 575.Windows 系统错误消息为: {应用程序错误}应用程序无法正常启动(0x%lx).请单击“确定 ...
- windows核心编程---第六章 线程的调度
每个线程都有一个CONTEXT结构,保存在线程内核对象中.大约每隔20ms windows就会查看所有当前存在的线程内核对象.并在可调度的线程内核对象中选择一个,将其保存在CONTEXT结构的值载入c ...
- delphi的多线程编程
多线程的基本概念 win 98/nt/2000/xp 是个多任务操作系统,也就是:一个进程可以划分为多个线程,每个线程轮流占用cpu 运行时间和资源,或者说,把cpu 时间划成片,每个片分给不同的线程 ...
- AcceptEx编辑
Windows套接字AcceptEx函数接受一个新的连接,返回本地和远程地址,并接收由客户端应用程序发送的第一块数据.Windows 95/98不支持AcceptEx函数. 平台SDK:Windows ...
- MFC菜单、工具栏和状态栏
菜单:CMenu类 CMenu类的主要成员函数 BOOL LoadMenu(UINT nIDResource); 加载菜单资源,并将其附加到CMenu对象上.参数nIDResource指定了要加载的菜 ...
随机推荐
- js格式化日期工具类
就是一个工具类 开箱即用 传进一个指定的参数,格式化 //将时间戳格式化 function getMyDate(time){ if(typeof(time)=="undefined&quo ...
- JAVA记录-WebService开发部署
JWS.Axis2.cxf 1.下载axis2.war和axis2.bin.zip 2.将axis2.war包部署到Tomcat下,启动Tomcat测试:http://localhost:8089/a ...
- Spark简介安装和简单例子
Spark简介安装和简单例子 Spark简介 Spark是一种快速.通用.可扩展的大数据分析引擎,目前,Spark生态系统已经发展成为一个包含多个子项目的集合,其中包含SparkSQL.Spark S ...
- jackson的自动检测机制
jackson允许使用任意的构造方法或工厂方法来构造实例 使用@JsonAutoDetect(作用在类上)来开启/禁止自动检测 fieldVisibility:字段的可见级别 ANY:任何级别的字段都 ...
- 宕机不等于关机,阴魂不散的vm
今天早上刚到公司,就发现研发环境的机器连不上了. 公司研发环境的部署比较简单,物理机上装VMware Esxi 6 ,然后在esxi上装虚机. 检查发现:esxi ping不通,客户端也连不上:物理机 ...
- python学习笔记8--面向对象--属性和方法详解
属性: 公有属性 (属于类,每个类一份) 普通属性 (属于对象,每个对象一份) 私有属性 (属于对象,跟普通属性相似,只是不能通过对象直接访问) 方法:(按作用) 构造方法 析构函数 方法: ...
- C# 窗体内有子控件时鼠标检测
public partial class FormPop : Form { public FormPop() { InitializeComponent(); } private void FormP ...
- Bleve代码阅读(一)——新建索引
引言 Bleve是Golang实现的一个全文检索库,类似Lucene之于Java.在这里通过阅读其代码,来学习如何使用及定制检索功能.也是为了通过阅读代码,学习在具体环境下Golang的一些使用方式. ...
- c/s 给 服务器上传文件(c/s和b/s互传文件)
//c/s 代码 private void button1_Click(object sender, EventArgs e) { OpenFileDialog openFileDialog = ne ...
- ==========2014-04-24=========winform树控件勾选方法 和获取所有选中的
http://bbs.bccn.net/thread-197567-1-1.html /// <summary> /// 已选中或取消选中树节点上的复选框时 /// </summar ...