Understanding ulimit -u

I'd like to understand what's going on here.

linvx$ ( ulimit -u 123; /bin/echo nst )
nst

linvx$ ( ulimit -u 122; /bin/echo nst )
-bash: fork: Resource temporarily unavailable
Terminated

linvx$ ( ulimit -u 123; /bin/echo one; /bin/echo two; /bin/echo three )
one
two
three

linvx$ ( ulimit -u 123; /bin/echo one & /bin/echo two & /bin/echo three )
-bash: fork: Resource temporarily unavailable
Terminated
one

I speculate that the first 122 processes are consumed by Bash itself, and that the remaining ulimit governs how many concurrent processes I am allowed to have. The documentation is not very clear on this. Am I missing something?

More importantly, for a real-world deployment, how can I know what sort of ulimit is realistic? It's a long-running daemon which spawns worker threads on demand, and reaps them when the load decreases. I've had it spin the server to its death a few times. The most important limit is probably memory, which I have now limited to 200M per process, but I'd like to figure out how I can enforce a limit on the number of children (the program does allow me to configure a maximum, but how do I know there are no bugs in that part of the code?)


Addendum: On a newer system, I get a higher number and slightly different behavior.

xubuntu12.04$ ( ulimit -u 206; /bin/echo nst )
nst

xubuntu12.04$ ( ulimit -u 205; /bin/echo nst )
bash: fork: retry: No child processes
bash: fork: retry: No child processes
bash: fork: retry: No child processes
bash: fork: retry: No child processes
bash: fork: Resource temporarily unavailable
Terminated

xubuntu12.04$ bash --version
GNU bash, version 4.2.24(1)-release (x86_64-pc-linux-gnu)
Copyright (C) 2011 Free Software Foundation, Inc.
License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html>

This is free software; you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law.

The older system had Bash v3 I believe.

In dash, I get different behavior, albeit still not the behavior I expect (and the option is called -p instead of -u):

xubuntu12.04$ dash

$ ( ulimit -p 1; /bin/echo nst )
nst

$ ( ulimit -p 2; /bin/echo nst & /bin/echo too & )
dash: 0: Cannot fork

$ ( ulimit -p 208; /bin/echo nst & /bin/echo too & )
dash: 0: Cannot fork
nst

$ ( ulimit -p 209; /bin/echo nst & /bin/echo too & )
nst
too

Solution 1:

It's not only the subprocesses in the subshell that count against the limit, but everything on the system under your uid.

Thus, if you have 200 processes running as yourself anywhere on the system, a process with ulimit -u 205 will only be able to fork until the total count reaches 205 -- that is, five times (if nothing exits).

Solution 2:

This is the way ulimit works.

If you wish to allow one user 4 running processes,

you would have 1+4 (one is for the bash process that the user is currently using)

From my tests,

created a user test,

ran ulimit -u 1

could not run any commands as bash already a running process,

ran ulimit -u 2

can only run one process, example,

ps aux -> returned value but ps aux | grep test -> did not return as it's using 2 processes

Lastly using ulimit on your root account is not recommended, ulimit is mostly used for large multi user environments.

I hope this helps!

Cheers,

===============

 -a     All current limits are reported
 -b     The maximum socket buffer size
 -c     The maximum size of core files created
 -d     The maximum size of a process’s data segment
 -e     The maximum scheduling priority ("nice")
 -f     The maximum size of files written by the shell and its children
 -i     The maximum number of pending signals
 -l     The maximum size that may be locked into memory
 -m     The maximum resident set size (many systems do not honor this limit)
 -n     The maximum number of open file descriptors (most systems do not allow  this
                     value to be set)
 -p     The pipe size in 512-byte blocks (this may not be set)
 -q     The maximum number of bytes in POSIX message queues
 -r     The maximum real-time scheduling priority
 -s     The maximum stack size
 -t     The maximum amount of cpu time in seconds
 -u     The maximum number of processes available to a single user
 -v     The maximum amount of virtual memory available to the shell
 -x     The maximum number of file locks
 -T     The maximum number of threads