Можно ли предотвратить дочерние процессы, наследующие родство процессора / ядра от родителя?
Мне особенно интересно делать это на Linux, в отношении программ на Java. Уже есть несколько вопросов, в которых говорится, что у вас нет контроля со стороны Java, а некоторые RFE закрыты Sun/Oracle.
Если у вас есть доступ к исходному коду и вы используете язык низкого уровня, вы, безусловно, можете сделать соответствующие системные вызовы. Однако системы в песочнице - возможно, без исходного кода - представляют собой еще большую проблему. Я бы подумал, что инструмент для установки этого процесса или параметра ядра способен контролировать это извне родительского процесса. Это действительно то, что я после.
Я понимаю причину, почему это по умолчанию. Похоже, что некоторые версии Windows могут разрешать это, но большинство этого не делают. Я ожидал, что Linux разрешит контроль над ним, но, похоже, это не вариант.
2 ответа
То, что вы также можете сделать, это изменить родство дочернего элемента от родительского после fork(). Между прочим, я предполагаю, что вы работаете в Linux, некоторые из этих вещей, такие как получение количества ядер с помощью sysconf(), будут отличаться в разных версиях ОС и Unix.... В этом примере показан процессор родительского процесса и пытается гарантировать, что все дочерние процессы запланированы на другом ядре, в циклическом переборе.
/* get the number of cpu's */
numcpu = sysconf( _SC_NPROCESSORS_ONLN );
/* get our CPU */
CPU_ZERO(&mycpuset);
sched_getaffinity( getpid() , sizeof mycpuset , &mycpuset);
for(i=0 ; i < numcpu ; i++ )
{
if(CPU_ISSET( i, &mycpuset))
{
mycpu = i;
break;
}
}
//...
while(1)
{
//Some other stuff.....
/* now the fork */
if((pid = fork()) == 0)
{
//do your child stuff
}
/* Parent... can schedule child. */
else
{
cpu = ++cpu % numcpu;
if(cpu == mycpu)
cpu = ++cpu % numcpu;
CPU_ZERO(&mycpuset);
CPU_SET(cpu,&mycpuset);
/*set processor affinity*/
sched_setaffinity(pid, sizeof mycpuset, &mycpuset );
//any other father stuff
}
}
Если у вас есть достаточные привилегии, вы можете просто позвонить setaffinity, прежде чем изгнать ребенка. Другими словами, из
if (fork() == 0)
execve("prog", "prog", ...);
перейти к использованию
/* simple example using taskset rather than setaffinity directly */
if (fork() == 0)
execve("taskset", "taskset", "-c", "0-999999", ...);
[Конечно, использование 999999 нехорошо, но его можно заменить программой, которая автоматически определяет число процессоров и сбрасывает маску сродства по желанию.]