以下建议的代码:
- 干净地编译
- 无法执行所需的功能(?为什么?)
- 包含所有需要的头文件
- 只有“父”尝试创建子进程
- 注意:OP 和提议的程序都退出而不等待子进程完成。IE 主程序应该是调用
wait()
或wait_pid()
为每个子进程启动的。
- 注意:对
sleep(1)
保持输出良好和有条理的调用。但是,在此期间sleep
子进程完成并退出,因此实际上任何时候只有 1 个子进程在运行,因此即使调用setrlimit()
成功,“fork()”循环也可能永远运行。
现在,建议的代码:
#include <stdio.h>
#include <stdlib.h>
#include <sys/time.h>
#include <sys/resource.h>
#include <sys/types.h>
#include <unistd.h>
int main( void )
{
struct rlimit rlim;
rlim.rlim_cur = rlim.rlim_max = 4;
if( getrlimit(RLIMIT_NPROC, &rlim) == -1 )
{
perror( "getrlimit failed" );
exit( EXIT_FAILURE );
}
if( setrlimit(RLIMIT_NPROC, &rlim) == -1 )
{
perror( "setrlimit failed" );
exit( EXIT_FAILURE );
}
for (int i = 0; i < 4; ++i)
{
pid_t pid = fork();
switch( pid )
{
case -1:
perror( "fork failed" );
exit( EXIT_FAILURE );
break;
case 0:
printf( "child pid: %d\n", getpid() );
exit( EXIT_SUCCESS );
break;
default:
printf( "parent pid: %d\n", getpid() );
break;
}
sleep(1);
}
return 0;
}
运行程序会导致:
fork failed: Resource temporarily unavailable
这表明调用有问题setrlimit()
从手册页:
RLIMIT_NPROC
This is a limit on the number of extant process (or, more pre‐
cisely on Linux, threads) for the real user ID of the calling
process. So long as the current number of processes belonging
to this process's real user ID is greater than or equal to this
limit, fork(2) fails with the error EAGAIN.
The RLIMIT_NPROC limit is not enforced for processes that have
either the CAP_SYS_ADMIN or the CAP_SYS_RESOURCE capability.
所以,调用setrlimit()
是限制线程的数量,而不是子进程的数量
但是,如果我们在调用之后立即添加几个打印语句getrlimit()
并在调用结果之后再次添加setrlimit()
:
if( getrlimit(RLIMIT_NPROC, &rlim) == -1 )
{
perror( "getrlimit failed" );
exit( EXIT_FAILURE );
}
printf( "soft limit: %d\n", (int)rlim.rlim_cur );
printf( "hard limit: %d\n\n", (int)rlim.rlim_max );
if( setrlimit(RLIMIT_NPROC, &rlim) == -1 )
{
perror( "setrlimit failed" );
exit( EXIT_FAILURE );
}
if( getrlimit(RLIMIT_NPROC, &rlim) == -1 )
{
perror( "getrlimit failed" );
exit( EXIT_FAILURE );
}
printf( "soft limit: %d\n", (int)rlim.rlim_cur );
printf( "hard limit: %d\n\n", (int)rlim.rlim_max );
那么结果是:
soft limit: 27393
hard limit: 27393
soft limit: 27393
hard limit: 27393
parent pid: 5516
child pid: 5517
parent pid: 5516
child pid: 5518
parent pid: 5516
child pid: 5519
parent pid: 5516
child pid: 5520
这表明调用:setrlimit()
实际上并没有改变子进程的限制
注意:我正在运行 ubuntu linux 18.04