После форка с execve не может синхронизировать процесс ожидания

У меня проблема в C с execve после форка. Мне нужно создать 20 детей, и только когда они будут успешно созданы, я буду делать что-то. Я использую для этого семафор, но он все еще не работает, потому что в файле execve, который я запускаю после форка, он читает последние 2 или 3 дочерних элемента. Но я хочу "остановить" файл и заставить его ждать создания.

Взгляните на мой код: Father.c

system("gcc person.c -o Person");
for(i = 0; i < NUM_PEOPLE; i++){
 if((pidprocesso = fork()) == 0) {

  // Insert in one struct
  insertInStruct(randType, randName, randDna, getpid(), 1, i);

  // Semaphore that have init val to NUM_PEOPLE
  reserve(sem_totchild); // This make a -1 operation

  char *argv[] = {"0", "1", "2", "stuff", NULL}; 

  execve("./Person", argv, NULL);
 }
}

человек.с

while((semctl(sem_totchild, 0, GETVAL)) > 0){

  // Something to wait the end of creation
  // And I can't use sleep()
}

  // Code that will run after creation

Очевидно, я хорошо связал семафор во всех двух файлах.


person Riccardo Calabrese    schedule 04.12.2017    source источник
comment
Возможный дубликат блокирующих дочерних элементов семафора   -  person PSkocik    schedule 05.12.2017
comment
Необходимо использовать semop() с semval равным 0. Если семпахора инициируется до 20 и уменьшается на единицу, а также каждое дочернее создание, у вас будет рандеву.   -  person Jean-Baptiste Yunès    schedule 05.12.2017
comment
Нет дубликата семафора.   -  person Riccardo Calabrese    schedule 05.12.2017
comment
Один из простых способов синхронизации дочерних элементов — это открытие родителем канала и запуск всех дочерних элементов. Затем он закрывает оба конца трубы. Потомки немедленно закрывают конец канала для записи, а затем пытаются прочитать один байт из канала. Ни один байт не приходит, но когда канал закрывается, все они получают сообщение и могут также закрыть конец канала для чтения и продолжить работу. Простой, эффективный, портативный.   -  person Jonathan Leffler    schedule 05.12.2017
comment
Обратите внимание, что ваши массивы argv сообщают программе Person, что она называется 0. С execve() приходит большая сила и ответственность; вы можете называть программу как угодно, но вы должны называть ее как-то. Из вашего кода неясно (который не является MCVE (минимальный воспроизводимый пример), я отмечаю), почему вы думаете, что семафоры System V IPC будут доступны в коде person.c; вы не показали, как он соединяется с семафорами и т. д. Я думаю, вам следует использовать semop(), а не semctl().   -  person Jonathan Leffler    schedule 05.12.2017
comment
Я хорошо связал семафор, потому что в обоих файлах .c у меня есть sem_totchild = semget(KEYSEM_TC, 1, IPC_CREAT | PERMISSION), где KEYSEM_TC является константой, определяемой с файлом config.h.   -  person Riccardo Calabrese    schedule 05.12.2017
comment
по поводу: char *argv[] = {"0", "1", "2", "stuff", NULL}; execve("./Person", argv, NULL); это неправильно, должно быть: char *argv[] = {"Person", "0", "1", "2", "stuff", NULL}; execve("*argv, argv, NULL); perror( "execve failed"); exit( EXIT_FAILURE );   -  person user3629249    schedule 06.12.2017
comment
программы должны использовать семафор NAMED, чтобы его можно было использовать в разных процессах. Помимо прочего, имя должно начинаться с /. Правильная функция для вызова общего/именованного семафора: sem_open()   -  person user3629249    schedule 06.12.2017
comment
этот семафор содержит множество ошибок в выбранном ответе , но первые несколько строк ответа показывают, как использовать именованный семафор. Обратите внимание, что все процессы должны использовать одно и то же имя (в отличие от связанного ответа)   -  person user3629249    schedule 06.12.2017
comment
@Jean-Baptiste Yunès. Когда вы написали: Необходимо использовать semop() с semval равным 0, вы имели в виду … с sem_op равным 0?   -  person Armali    schedule 23.08.2019