следующий предложенный код:
- безупречная компиляция
- не может выполнить желаемую функциональность (? Почему?)
- включает все необходимые заголовочные файлы
- только «родитель» пытается создать дочерние процессы
- примечание: 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