¿Los procesos hijos bifurcados usan el mismo semáforo?

Digamos que creo un semáforo. Si doy varios procesos hijos, ¿seguirán usando el mismo semáforo?

Además, supongamos que creo una estructura con semáforos dentro y bifurcada. ¿Todos los procesos hijo todavía usan ese mismo semáforo? De lo contrario, ¿almacenar los struct + semáforos en la memoria compartida permitirá que los procesos secundarios usen los mismos semáforos?

Estoy realmente confundido acerca de cómo los procesos de mi hijo bifurcado pueden usar los mismos semáforos.

Digamos que creo un semáforo. Si doy varios procesos hijos, ¿seguirán usando el mismo semáforo?

Si está utilizando un semáforo semctl IPC ( semctl ), entonces sí. Si está utilizando semáforos POSIX ( sem_init ), entonces sí, pero solo si pasa un valor verdadero para el argumento pshared en la creación y lo coloca en la memoria compartida.

Además, supongamos que creo una estructura con semáforos dentro y bifurcada. ¿Todos los procesos hijo todavía usan ese mismo semáforo? De lo contrario, ¿almacenar los struct + semáforos en la memoria compartida permitirá que los procesos secundarios usen los mismos semáforos?

¿Qué quieres decir con ser ‘semáforos adentro’? Las referencias a los semáforos IPC SysV se compartirán, porque los semáforos no pertenecen a ningún proceso. Si está utilizando semáforos POSIX o construye algo a partir de mutexes y condvars pthreads, necesitará usar memoria compartida, y el atributo pshared (pthreads tiene un atributo pshared para condvars y mutexes también)

Tenga en cuenta que los mmaps anónimos creados con el indicador MAP_SHARED cuentan como memoria compartida (anónima) para estos fines, por lo que no es necesario crear realmente un segmento de memoria compartida con nombre. La memoria del montón común no se compartirá después de un tenedor .

Digamos que creo un semáforo. Si doy varios procesos hijos, ¿seguirán usando el mismo semáforo?

Depende de cómo haya creado el semáforo, para hacer eso con un semáforo de IPC vea semáforo.c: Ilustración del semáforo simple que pasa para un ejemplo.

Además, supongamos que creo una estructura con semáforos dentro y bifurcada. ¿Todos los procesos hijo todavía usan ese mismo semáforo? De lo contrario, ¿almacenar los struct + semáforos en la memoria compartida permitirá que los procesos secundarios usen los mismos semáforos?

Para que funcione, su semáforo debe almacenarse en un área compartida entre el proceso principal y el secundario, como la memoria compartida, y no solo creado en la stack o en el montón porque se copiará cuando el proceso se bifurca.

Estoy realmente confundido acerca de cómo los procesos de mi hijo bifurcado pueden usar los mismos semáforos.

El semáforo se puede compartir a través de subprocesos o procesos. El intercambio de procesos cruzados se implementa en el nivel del sistema operativo. Dos o más procesos diferentes pueden compartir el mismo semáforo incluso si esos procesos no se crearon mediante la bifurcación de un proceso principal único.

Vea este ejemplo para compartir un semáforo UNIX sin nombre entre un proceso padre y su hijo (para comstackr con gcc, necesitará el indicador -pthread ):

 #include  #include  #include  #include  #include  #include  #include  #include  #include  int main(void) { /* place semaphore in shared memory */ sem_t *sema = mmap(NULL, sizeof(*sema), PROT_READ |PROT_WRITE,MAP_SHARED|MAP_ANONYMOUS, -1, 0); if (sema == MAP_FAILED) { perror("mmap"); exit(EXIT_FAILURE); } /* create/initialize semaphore */ if ( sem_init(sema, 1, 0) < 0) { perror("sem_init"); exit(EXIT_FAILURE); } int nloop=10; int pid = fork(); if (pid < 0) { perror("fork"); exit(EXIT_FAILURE); } if (pid == 0) { /* child process*/ for (int i = 0; i < nloop; i++) { printf("child unlocks semaphore: %d\n", i); if (sem_post(sema) < 0) { perror("sem_post"); } sleep(1); } if (munmap(sema, sizeof(sema)) < 0) { perror("munmap"); exit(EXIT_FAILURE); } exit(EXIT_SUCCESS); } if (pid > 0) { /* back to parent process */ for (int i = 0; i < nloop; i++) { printf("parent starts waiting: %d\n", i); if (sem_wait(sema) < 0) { perror("sem_wait"); } printf("parent finished waiting: %d\n", i); } if (sem_destroy(sema) < 0) { perror("sem_destroy failed"); exit(EXIT_FAILURE); } if (munmap(sema, sizeof(sema)) < 0) { perror("munmap failed"); exit(EXIT_FAILURE); } exit(EXIT_SUCCESS); } } 

El resultado será:

 parent starts waiting: 0 child unlocks semaphore: 0 parent finished waiting: 0 parent starts waiting: 1 child unlocks semaphore: 1 parent finished waiting: 1 ... 

También es posible que desee leer los semáforos en Linux , pero tenga en cuenta que el ejemplo de los semáforos de UNIX en el tenedor dado no funciona porque el autor olvidó usar el indicador MAP_ANONYMOUS en mmap .

Prueba esto

el niño y el padre incrementarían la variable compartida alternativamente

 #include  #include  #include  #include  #include  #include  #include  #include  #include  struct test { sem_t mutex1; sem_t mutex2; int temp; }test1; int main(int argc, char **argv) { int fd, i,count=0,nloop=10,zero=0,*ptr; struct test *testptr; //open a file and map it into memory sem_t mutex; fd = open("log.txt",O_RDWR|O_CREAT,S_IRWXU); write(fd,&zero,sizeof(int)); ptr = mmap(NULL, sizeof(struct test),PROT_READ |PROT_WRITE,MAP_SHARED,fd,0); close(fd); memcpy(ptr, &test1, sizeof(test1)); testptr = (struct test *)ptr; // testptr = (struct test *)&test1; /* create, initialize semaphore */ if( sem_init(&(testptr->mutex1),1,1) < 0) { perror("semaphore initilization"); exit(0); } /* create, initialize semaphore */ if( sem_init(&(testptr->mutex2),1,0) < 0) { perror("semaphore initilization"); exit(0); } if (fork() == 0) { /* child process*/ for (i = 0; i < nloop; i++) { sem_wait(&(testptr->mutex2)); printf("child: %d\n", testptr->temp++); sem_post(&(testptr->mutex1)); } exit(0); /* back to parent process */ for (i = 0; i < nloop; i++) { sem_wait(&testptr->mutex1); printf("parent: %d\n", testptr->temp++); sem_post(&(testptr->mutex2)); } exit(0); }