以下建议的代码:
- 干净编译
- 未能执行所需的功能(?为什么?)
- 包含所有需要的头文件
- 只有“父”尝试创建子进程
- 注意: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()有问题
来自 MAN 页面:
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