pthread_create() blocks if maxthreads reached?

Daniel Eischen eischen at vigrid.com
Sun Feb 1 11:27:17 PST 2004


On Sun, 1 Feb 2004, Julian Elischer wrote:
>=20
> On Sun, 1 Feb 2004, Petri Helenius wrote:
>=20
> > Craig Rodrigues wrote:
> >=20
> > >Understood.  Keep in mind, I am trying to "kick the tires"
> > >on libpthread, to see how it reacts on crazy corner cases.
> > >I can certainly increase the values of these sysctls,
> > >but I think that pthread_create() should not block if
> > >it hits a limit.
> > >
> > > =20
> > >
> > I agree here, pthread_create() should not get blocked sitting somewhere=
=20
> > because
> > it would easily lead to situations where a "main" thread spawning off=
=20
> > children
> > is blocked and cannot report errors or pthread_join() threads that term=
inate
> > because of it=B4s blocked.
>=20
> pthread_create() is not blocking..
>=20
> Pthread_create doesn't result in a system call.
> creating new threads si a purely userland activity,
> (well, the malloc for the thread may call sbreak, but as you are running
> in the thread library that might be a synchronous activity anyhow I
> think.. (Dan, does pthread_create() count as an entry into the
> thread_scheduler?)

It can depending on whether there are other higher priority threads
waiting.  pthread_create() results in a couple of internal locks
being taken and can be (inherently) a preemption point.

> In any case if it blocked in sbreak() it would be
> awoken very quickly.
>=20
> To see what is happenning, you have to understand wow these threads
> work..
>=20
> when a thread enters the kernel and blocks, (**) a new kernel thread is
> created, made runnable, and set to make an upcal back to the Userland
> Thread Scheduler,(UTS) so that a new thread can be scheduled to replace
> the one that blocked. The new kernel thread is used for the next
> userland thread.. If the limit on kenrel threads is reached, then at the
> point marked "**" above, no new thread is created, so no upcall occurs.
>=20
> basically it's a shell game.. every time a kernel thread blocks, we
> create a new one for the process to use instead, until you run out. when
> we just don't make one. i.e. the syscall you made still blocks, but no
> replacement thread is delivered to teh process to keep running.
>=20
> The alternative would be to make EWOULDBLOCK a possible error return for
> EVERY syscall.. i.e if you did a select(2) as the test program does, and
> you recieved an EWOULDBLOCK.. what would you think/do?
>=20
> Noe that this all applies ONLY to threads blocked in the kernel. you may
> have thousands of threads in userland, blocked on userland constructs..
> they don't count. Only threads blocked while holding kernel resources.

And you can see this with the sample program that I included in
one of my last emails.  I tested it with 20000 threads and they
were all created just fine, but once they were running (blocked in
select()) the program quickly ran out of resources (kernel threads).

--=20
Dan Eischen



More information about the freebsd-threads mailing list