Отключите больше процессов как предыдущий, пока не будет достигнут максимум

Чтобы отключить X-процессы и сделать так, чтобы родитель ожидал всех, у меня есть следующий код:

int maxProcesses = 10;

for (int currentChild = 0; currentChild < maxProcesses; currentChild++) {
pid_t pid = fork();

if (pid < 0) {
// Error
} else if (pid == 0) {
// Child
} else {
// Parent
// Should I call waitpid on pid and wait here instead?
}
}

// Wait for all children
for (int currentChild = 0; currentChild < maxProcesses; currentChild++) {
wait(NULL);
}

Теперь я хотел бы изменить код так, чтобы из общего числа процессов X сначала удалялся Y, а затем, когда они заканчивали, делалось больше вилок, пока не было достигнуто желаемое общее число. Я внес некоторые изменения в приведенный выше код с некоторыми вопросами.

int totalProcessesToBeForked = 10;
int maxAllowedAtOnce = 5;

for (int currentChild = 0; currentChild < maxAllowedAtOnce; currentChild++) {
forkChild(currentChild);
}

// Wait for all children
// # How do I modify this to wait for new children forked as well
// # if I move it inside parent, it will make things easier, right?
for (int currentChild = 0; currentChild < maxAllowedAtOnce; currentChild++) {
wait(NULL);
}

void forkChild(currentChild) {
pid_t pid = fork();

if (pid < 0) {
// Error
} else if (pid == 0) {
// Child
} else {
// Parent
// # I think waiting here using waitpid will be better b/c
// # as new forks are made, parent begins to wait for them
}
}

Мне, вероятно, нужно будет подсчитать, сколько детей было разветвлено и сравнить их с totalProcessesToBeForked, и соответственно разветвлять новых.

Обновленный код v1:

int maxProcesses = 10;
int maxAllowedAtOnce = 5;

int main(int argc, char* argv[]) {
// Start timer
alarm(10);                  // Terminate after 10s
signal(SIGALRM, onTimeout);
signal(SIGCHLD, catchChild);

for (int currentChild = 0; currentChild < maxAllowedAtOnce; currentChild++) {
forkChild(currentChild);
}

// # This sections runs immediately before death of any child is reported
// # and starts cleanup processes, thus killing any/all running children

// Completed before timeout
endTimer = true;
int timeRemaining = alarm(0);
if (timeRemaining > 0) {
printf("\nCompleted w/ %is remaining. Performing cleanup.\n", timeRemaining);

// Kill children any running child processes, cleanup
cleanup();
}

return 0;
}

void forkChild(currentChild) {
pid_t pid = fork();

if (pid < 0) {
// Error
} else if (pid == 0) {
// Child
execl("/bin/date", "date", 0, 0);
} else {
// Parent
printf("#Log: Started %i.\n", currentChild + 1);
}
}

void catchChild(int sig) {
pid_t p;
int state;
p=wait(&state);
printf("Got child %d\n",p);
}

void cleanup() {
// Cleanup Code
}

Пример выполнения:

введите описание изображения здесь

Редактировать № 2:
http://ideone.com/noUs3m

0

Решение

Вместо того, чтобы использовать wait как вы уже сделали, вы хотите изучить обработку сигналов для обработки умирающих дочерних процессов.

Вы добавляете, прежде чем начать forkИнг, эта строка

signal(SIGCHLD,catchchild);

и эта функция для вашего кода

void catchchild(int sig)
{
pid_t p;
int state;
p=wait(&state);
printf("Got child %d\n",p);
}

и тогда, когда умирает дочерний процесс, ваш основной процесс будет вызывать catchchild,

Как вы уже выяснили, если у вас есть счетчик того, сколько детей было разветвлено, вы могли бы иметь catchchild обновить это так, чтобы ваш основной код знал fork новый ребенок

Чтобы ответить на ваш комментарий что-то вроде следующего, за исключением дополнительной проверки ошибок

while(totalProcessesToBeForked)
{
if(currentChild < maxAllowedAtOnce)
{
forkChild(currentChild);
totalProcessesToBeForked--;
}
sleep(1);
}
1

Другие решения

Других решений пока нет …

По вопросам рекламы [email protected]