Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

Re: Is there a thread number limit

121 views
Skip to first unread message

Relvinian

unread,
May 3, 2004, 2:23:55 PM5/3/04
to
Depending on what OS you are tyring to do this one, you will run into limits
on how many threads can be run at once (mainly from resource problems --
memory, etc ).

2000/XP will allow more then the 9x series.

I have seen up to over 500+ on 2000 before. ;-)

"Ying Rao" <rao...@hotmail.com> wrote in message
news:486BF0AE-6309-47B2...@microsoft.com...
> Hi,
> I'm developing a server application running as a console. I got the
problem that when the threads created reached a number(which varies on
different machines, from 122 to 192), the beginThreadEx function returns
error code 183.
> I tried to change the stack_size paramater of the beginThreadEx function,
the only difference was between 0 and a non-zero value, but a big value or a
small value do not have any difference.
> I also tried to change the stack memory and commit in the
Project/Setting/Linker, but that has no effect at all.
> The last thing I tried was to increase the virtual memory on my machine
but it doesn't matter either.
> Has anyone experienced this kind of problem?
> Please help.
>
>
> Sincerely
> Ying Rao


Trevor

unread,
May 3, 2004, 3:05:15 PM5/3/04
to
"Ying Rao" <rao...@hotmail.com> wrote in message
news:486BF0AE-6309-47B2...@microsoft.com...
> Hi,
> I'm developing a server application running as a console. I got the
problem that when the threads created reached a number(which varies on
different machines, from 122 to 192), the beginThreadEx function returns
error code 183.
> I tried to change the stack_size paramater of the beginThreadEx function,
the only difference was between 0 and a non-zero value, but a big value or a
small value do not have any difference.
> I also tried to change the stack memory and commit in the
Project/Setting/Linker, but that has no effect at all.
> The last thing I tried was to increase the virtual memory on my machine
but it doesn't matter either.

Ying,

Changing the stack size for a thread may help if you are getting stack
overflows in the thread. I am not sure where you got error code 183 from.
If you are calling _beginthreadex it will return 0 on failure. You then
check the value of errno (or doserrno) to find out why it failed. According
to MSDN docs there are only two returns: EAGAIN (error # 11 - too many
threads) and EINVAL (error # 22 - invalid stack size/argument). It sounds
to me like you have too many threads open. You may need to re-evaluate your
server design. You can get the most performance out of IOCP (IO Completion
Ports). IOCP is hard to program and limits your server to only running on
the NT kernel (NT4/2000/XP/2003). The de-facto book for IOCP (and other
nice advanced NT kernel stuff) is "Programming Server-Side Applications for
Microsoft Windows 2000" by Jeffrey Richter & Jason D. Clark. This book may
be out of print but I recently (within the last month) bought it at
Amazon.com. You can implement something similar to a HTTP server where a
thread is spawned for each connection, but the thread is killed after the
connection finishes a transaction. Of course, this may not fit your needs.
You can also use one thread for Winsock and just have it walk through your
list of clients every second and call select() to see if there is work to be
done. There are countless ways to do this. If there are indeed too many
open threads then you may think about re-evaluating your server design.
HTH.


Rob Vermeulen

unread,
May 3, 2004, 5:03:45 PM5/3/04
to
Hi Ying,

You should check the result the beginThreadEx gives you. This will indicate
if there are too many threads running, or if there's a stack overflow.

I think the best idea is to reconsider your server design. Try creating a
thread pool instead of a new thread for every connection. This way you
always have a certain number of threads running from which you pick one,
every time a connection is made.

Search for the word "Concurrent Server" in google to find out how to build a
good server without using too much resources. A good concurrent server uses
only the necessary threads and provides a good mechanism for handling
"orphans" (threads with a lost connection).

Good luck!

Rob.

"Ying Rao" <rao...@hotmail.com> wrote in message
news:486BF0AE-6309-47B2...@microsoft.com...
> Hi,
> I'm developing a server application running as a console. I got the
problem that when the threads created reached a number(which varies on
different machines, from 122 to 192), the beginThreadEx function returns
error code 183.
> I tried to change the stack_size paramater of the beginThreadEx function,
the only difference was between 0 and a non-zero value, but a big value or a
small value do not have any difference.
> I also tried to change the stack memory and commit in the
Project/Setting/Linker, but that has no effect at all.
> The last thing I tried was to increase the virtual memory on my machine
but it doesn't matter either.

Joseph M. Newcomer

unread,
May 3, 2004, 10:03:06 PM5/3/04
to
MS-DOS systems may have limits; I once wrote a little demo program that created 5000
threads, just to prove it could be done on Windows. I don't recall what the limit was, but
it is huge.

Error code 183 is pretty meaningless. I presume you mean that when _beginthreadex returns
a 0 handle, that ::GetLastError() returns 183 (note that ::GetLastError is meaningless
unless you have actually had independent verification of an error condition).

Usually, changing the stack size is the biggest factor in the practical thread limit,
although when you are creating a couple hundred threads, I begin to question whether or
not the architecture of your program is sensible.

You didn't say which OS you were doing this on. This is critical information. On
MS-DOS-based systems (Win9x/Me), there are so many artificially tiny limits that a limit
in this range would not surprise me at all.

What are you trying to do that requires so many threads? There are often alternative
solutions, such as thread pools or fibers, depending on what you are trying to achieve.
joe

On Mon, 3 May 2004 09:46:19 -0700, "Ying Rao" <rao...@hotmail.com> wrote:

>Hi,
>I'm developing a server application running as a console. I got the problem that when the threads created reached a number(which varies on different machines, from 122 to 192), the beginThreadEx function returns error code 183.
>I tried to change the stack_size paramater of the beginThreadEx function, the only difference was between 0 and a non-zero value, but a big value or a small value do not have any difference.
>I also tried to change the stack memory and commit in the Project/Setting/Linker, but that has no effect at all.
>The last thing I tried was to increase the virtual memory on my machine but it doesn't matter either.
>Has anyone experienced this kind of problem?
>Please help.
>
>
>Sincerely
>Ying Rao

Joseph M. Newcomer [MVP]
email: newc...@flounder.com
Web: http://www.flounder.com
MVP Tips: http://www.flounder.com/mvp_tips.htm

Trevor

unread,
May 4, 2004, 12:11:33 PM5/4/04
to

"Ying Rao" <anon...@discussions.microsoft.com> wrote in message
news:6DEBC266-0197-4137...@microsoft.com...
> Thank you all for your help. The OS I'm using are WinNT and Win2000
server. I think they should allow more threads than I got. The number I can
create on WinNT is a little more than on Win2000 but not significant.
> The 183 error code is indeed by calling GetLastError(). Trevor mentioned
errno, is that a system paramter I can read or by calling some functions?
> Actually our architecure was changed to this recently because the requests
got stuck in queue, so we let the threads stay instead of being created on
the dispatch of each request. It indeed solved the problem but we got this
new trouble.

errno is a global int variable. If you can't reference it then just extern
it. A lot of the CRT functions and the functions inherited from UNIX set
this value to an errorcode and then set errno to the reason the error
occurred. This is similar to how Windows functions typically return != 0 on
error and you use GetLastError() to find out the reason. The problem is
that only Windows functions set the "last error". _beginthreadex is not a
Windows function. If in doubt, consult MSDN.


Doug Harrison [MVP]

unread,
May 4, 2004, 1:05:37 PM5/4/04
to
Trevor wrote:

>errno is a global int variable. If you can't reference it then just extern
>it.

Never "just extern" anything if you can help it. To use errno, #include
<errno.h>. In particular, errno is a macro, which expands to a modifiable
lvalue of type int. It may not be a global int at all, and in fact, it isn't
in VC's multithreaded CRT:

#if defined(_MT) || defined(_DLL)
_CRTIMP extern int * __cdecl _errno(void);
#define errno (*_errno())
#else /* ndef _MT && ndef _DLL */
_CRTIMP extern int errno;
#endif /* _MT || _DLL */

--
Doug Harrison
Microsoft MVP - Visual C++

Relvinian

unread,
May 4, 2004, 4:07:25 PM5/4/04
to
Trevor,

A error code of 183 (decimal) which is B7 hex equates to:
"Cannot create a file when that file already exists."

So, with this message, this leads me to believe your threads are clashing
with each other on trying to create files. You are somehow creating a file
in a shared mode that isn't compatible when another thread tries to do the
same operation on the same file.

I would double check your code for bugs. The number of threads isn't the
issue here.

"Trevor" <tre...@nospam.com> wrote in message
news:uyYucJfM...@TK2MSFTNGP09.phx.gbl...

Joseph M. Newcomer

unread,
May 4, 2004, 4:04:58 PM5/4/04
to
While _beginthreadex is not a Windows funciton, it DOES call CreateThread (the one and
ONLY way a thread can be created (ok, purists, there;s CreateRemoteThread, but I digress).
_beginthreadex is only a wrapper on CreateThread. If you read the code in thread.c, which
is the source code for _beginthreadex, you will see that it leaves the GetLastError() code
from CreateThread untouched, and merely maps it to errno, so GetLastError() will indicate
the reason CreateThread failed. Unfortunately, error 183 is ERROR_ALREADY_EXISTS, saying
that the file cannot be created because it already exists. This is what I find strange.
joe

Joseph M. Newcomer [MVP]

Jerry Coffin

unread,
May 5, 2004, 12:50:32 AM5/5/04
to
In article <g5tf9014rrcccprd7...@4ax.com>,
newc...@flounder.com says...

> While _beginthreadex is not a Windows funciton, it DOES call CreateThread (the one and
> ONLY way a thread can be created (ok, purists, there;s CreateRemoteThread, but I digress).

For true purists, there are also ZwCreateThread, RtlCreateUserThread,
NtCreateThread, etc., :-)

--
Later,
Jerry.

The universe is a figment of its own imagination.

Joseph M. Newcomer

unread,
May 6, 2004, 1:10:48 AM5/6/04
to
OK, if you want to drift into undocumented land...
joe

On Tue, 4 May 2004 22:50:32 -0600, Jerry Coffin <jco...@taeus.us> wrote:

>In article <g5tf9014rrcccprd7...@4ax.com>,
>newc...@flounder.com says...
>> While _beginthreadex is not a Windows funciton, it DOES call CreateThread (the one and
>> ONLY way a thread can be created (ok, purists, there;s CreateRemoteThread, but I digress).
>
>For true purists, there are also ZwCreateThread, RtlCreateUserThread,
>NtCreateThread, etc., :-)

Joseph M. Newcomer [MVP]

Jerry Coffin

unread,
May 6, 2004, 10:03:25 AM5/6/04
to
In article <76ij90hmespnuhdbb...@4ax.com>,
newc...@flounder.com says...

> OK, if you want to drift into undocumented land...

[ ... ]

> >For true purists, there are also ZwCreateThread, RtlCreateUserThread,
> >NtCreateThread, etc., :-)

Unless memory fails more than usual today, all of these are
documented. There's a difference between "Documented in the DDK" and
"undocumented".

Joseph M. Newcomer

unread,
May 6, 2004, 11:26:27 AM5/6/04
to
ZwCreateThread is documented with respect to the kernel, likewise RtlCreateUserThread. As
far as application programs are concerned, they do not exist. NtCreateThread, in
NTDLL.DLL, is part of the undocumented user API (e.g., Gary Nebbit's book).
joe

On Thu, 6 May 2004 08:03:25 -0600, Jerry Coffin <jco...@taeus.us> wrote:

>In article <76ij90hmespnuhdbb...@4ax.com>,
>newc...@flounder.com says...
>> OK, if you want to drift into undocumented land...
>
>[ ... ]
>
>> >For true purists, there are also ZwCreateThread, RtlCreateUserThread,
>> >NtCreateThread, etc., :-)
>
>Unless memory fails more than usual today, all of these are
>documented. There's a difference between "Documented in the DDK" and
>"undocumented".

Joseph M. Newcomer [MVP]

0 new messages