C/Visual C - Matar dos procesos hijos en C

   
Vista:

Matar dos procesos hijos en C

Publicado por Katerina (10 intervenciones) el 03/12/2016 13:17:04
Hola, tengo que hacer un programa en el que creo dos procesos hijos. Cuando pasen 5 segundos, hay que matar a los dos procesos hijos en orden, el segundo debe esperar a que muera el primero. No consigo que mueran los procesos. ¿Alguien podría echarme una mano? Gracias.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
void tiempo(int sig)
{
   kill(hijo1, SIGTERM);
   kill(hijo2, SIGTERM);
}
 
void funcion()
{
   printf("Se ha matado un proceso");
}
 
int main(int argc, char **argv)
{
   struct sigaction action;
   sigset_t new_mask;
 
   act.sa_flags = 0;
   act.sa_handler = &funcion;
   sigaction(SIGTERM, &action, NULL);
   sigemptyset(new_mask);
   sigaddset(&new_mask, SIGTERM);
 
   hijo1 = fork();
   switch(hijo1)
   {
      case 0:
         sigsuspend(&new_mask);
   }
   hijo2 = fork();
   switch(hijo2)
   {
      case 0:
         sigsuspend(&new_mask);
   }
   signal(SIGALRM, tiempo);
   alarm(5);
}
Valora esta pregunta
Me gusta: Está pregunta es útil y esta claraNo me gusta: Está pregunta no esta clara o no es útil
0
Responder

Matar dos procesos hijos en C

Publicado por Tom (515 intervenciones) el 03/12/2016 16:30:14
Tu problema es que sigsuspend probablemente funciona al revés de como piensas:

"In other words, the program is effectively suspended until one of the signals that is not a member of set arrives"
En tu caso, puedes usar SIGKILL para matar los procesos (sisgsuspend no llega a retornar, el proceso muere) o bloquear SIGTERM en el proceso hijo, justo antes de sigsuspend.

Mira el ejemplo del man de sigsuspend:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
sigset_t mask, oldmask;
 
 
/* Set up the mask of signals to temporarily block. */
sigemptyset (&mask);
sigaddset (&mask, SIGUSR1);
 
 
/* Wait for a signal to arrive. */
sigprocmask (SIG_BLOCK, &mask, &oldmask);
while (!usr_interrupt)
  sigsuspend (&oldmask);
sigprocmask (SIG_UNBLOCK, &mask, NULL);


Seguramente algo como esto funcionaría:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
#include <stdlib.h>
#include <unistd.h>
#include <stdio.h>
#include <signal.h>
#include <sys/wait.h>
 
pid_t hijo1, hijo2;
/* */
void tiempo(int sig) {
	printf("Killing childs ...\n");
	kill(hijo1, SIGKILL);
	kill(hijo2, SIGKILL);
}
 
/* */
void funcion() {
	printf("Someone is killed\n");
}
 
/* */
int main(int argc, char **argv) {
	struct sigaction action;
	sigset_t new_mask, oldmask;
	int exitcode;
 
	action.sa_flags = 0;
	action.sa_handler = funcion;
 
	sigaction(SIGTERM, &action, NULL);
	sigemptyset(&new_mask);
	sigaddset(&new_mask, SIGTERM);
 
	hijo1 = fork();
 
	switch(hijo1) {
	case 0:
		sigprocmask(SIG_BLOCK, &new_mask, &oldmask);
		sigsuspend(&new_mask);
	}
 
	hijo2 = fork();
 
	switch(hijo2) {
	case 0:
		sigprocmask(SIG_BLOCK, &new_mask, &oldmask);
		sigsuspend(&new_mask);
	}
 
	signal(SIGALRM, tiempo);
	alarm(5);
	wait(&exitcode);
	wait(&exitcode);
}
Valora esta respuesta
Me gusta: Está respuesta es útil y esta claraNo me gusta: Está respuesta no esta clara o no es útil
0
Comentar

Matar dos procesos hijos en C

Publicado por Katerina (10 intervenciones) el 03/12/2016 17:47:12
He probado el código, pero el programa termina sin entrar en funcion()...
Valora esta respuesta
Me gusta: Está respuesta es útil y esta claraNo me gusta: Está respuesta no esta clara o no es útil
0
Comentar

Matar dos procesos hijos en C

Publicado por Tom (515 intervenciones) el 03/12/2016 18:32:50
Ten en cuenta que sigsuspend() altera temporalmente la máscara de señales del proceso que lo invoca.

Además, para que funcione sigsuspend con SIGTERM, la has bloqueado previamente.

Una duda, ¿ ese código lo has hecho tú o lo has copiado ?
Valora esta respuesta
Me gusta: Está respuesta es útil y esta claraNo me gusta: Está respuesta no esta clara o no es útil
0
Comentar

Matar dos procesos hijos en C

Publicado por Tom (515 intervenciones) el 03/12/2016 18:57:56
Para hacer lo que dices (que se ejecute el manejador de la señal) habría que cambiar mi ejemplo.
(Pero probablemente podrías resolver el problema de otra manera, lo he hecho así por seguir tu código)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
#include <stdlib.h>
#include <unistd.h>
#include <stdio.h>
#include <signal.h>
#include <sys/wait.h>
 
pid_t hijo1, hijo2;
 
void tiempo(int sig) {
	printf("Killing childs ...\n");
	kill(hijo1, SIGTERM);
	kill(hijo2, SIGTERM);
}
 
/* */
void funcion() {
	printf("Someone is killed\n");
}
 
/* */
int main(int argc, char **argv) {
	struct sigaction action;
	sigset_t new_mask, oldmask;
	int exitcode;
 
	action.sa_flags = 0;
	action.sa_handler = funcion;
 
	sigaction(SIGTERM, &action, NULL);
	sigemptyset(&new_mask);
	sigaddset(&new_mask, SIGTERM);
 
	hijo1 = fork();
 
	switch(hijo1) {
	case 0:
		sigfillset(&new_mask);
		sigdelset(&new_mask, SIGTERM);
		sigsuspend(&new_mask);
		exit(0);
	}
 
	hijo2 = fork();
 
	switch(hijo2) {
	case 0:
		sigfillset(&new_mask);
		sigdelset(&new_mask, SIGTERM);
		sigsuspend(&new_mask);
		exit(0);
	}
 
	signal(SIGALRM, tiempo);
	alarm(5);
	wait(&exitcode);
	wait(&exitcode);
}
Valora esta respuesta
Me gusta: Está respuesta es útil y esta claraNo me gusta: Está respuesta no esta clara o no es útil
2
Comentar

Matar dos procesos hijos en C

Publicado por Katerina (10 intervenciones) el 03/12/2016 20:46:53
Sí, el código que puse lo hice yo. Gracias, ahora ya se ejecuta el manejador de la señal. Pero tengo una duda, si quisiera enviar una señal del hijo 1 al hijo 2 antes de matar los procesos, ¿dónde tendría que colocar
1
sigaction(SIGUSR1, &action, NULL);
para que salte a la función cuando reciba SIGUSR1 y muera si recibe SIGTERM? Porque lo puse en el hijo 2, pero no funciona...

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
#include <stdlib.h>
#include <unistd.h>
#include <stdio.h>
#include <signal.h>
#include <sys/wait.h>
 
pid_t hijo1, hijo2;
 
void tiempo(int sig) {
	printf("Killing childs ...\n");
	kill(hijo1, SIGTERM);
	kill(hijo2, SIGTERM);
}
 
/* */
void funcion() {
	printf("Se ha enviado una señal\n");
}
 
/* */
int main(int argc, char **argv) {
	struct sigaction action;
	sigset_t new_mask, oldmask;
	int exitcode;
 
	action.sa_flags = 0;
	action.sa_handler = funcion;
 
	sigaction(SIGTERM, &action, NULL);
	sigemptyset(&new_mask);
	sigaddset(&new_mask, SIGTERM);
 
	hijo1 = fork();
 
	switch(hijo1) {
	case 0:
                kill(hijo2, SIGUSR1);
                sigprocmask(SIG_BLOCK, &new_mask, &oldmask);
		sigsuspend(&new_mask);
	}
 
	hijo2 = fork();
 
	switch(hijo2) {
	case 0:
                sigaction(SIGUSR1, &action, NULL);
	        sigemptyset(&new_mask);
	        sigaddset(&new_mask, SIGUSR1);
                sigfillset(&new_mask);
		sigdelset(&new_mask, SIGUSR1);
		sigsuspend(&new_mask);
 
                sigprocmask(SIG_BLOCK, &new_mask, &oldmask);
		sigsuspend(&new_mask);
	}
 
	signal(SIGALRM, tiempo);
	alarm(5);
	wait(&exitcode);
	wait(&exitcode);
}
Valora esta respuesta
Me gusta: Está respuesta es útil y esta claraNo me gusta: Está respuesta no esta clara o no es útil
0
Comentar

Matar dos procesos hijos en C

Publicado por Tom (515 intervenciones) el 03/12/2016 21:08:32
Parece difícil que hayas podido llegar tan lejos sin entender como va esto ... ¿ no deberías leer la doc de sigsuspend() por lo menos ?

Describe un poco mejor lo que quieres hacer.
Valora esta respuesta
Me gusta: Está respuesta es útil y esta claraNo me gusta: Está respuesta no esta clara o no es útil
0
Comentar

Matar dos procesos hijos en C

Publicado por Katerina (10 intervenciones) el 04/12/2016 14:33:14
Yo lo que quiero es que el hijo 1 mande una señal al hijo 2 y salte a la manejadora, después que el hijo 2 mande otra señal al hijo 1 y salte a la manejadora, pero que al pasar 5 segundos se maten los procesos hijos. ¿Es posible hacerlo? Porque solo he visto ejemplos en los que el hijo espera por una señal...
Valora esta respuesta
Me gusta: Está respuesta es útil y esta claraNo me gusta: Está respuesta no esta clara o no es útil
0
Comentar

Matar dos procesos hijos en C

Publicado por Tom (515 intervenciones) el 04/12/2016 19:07:23
Sí, es posible. Y todo lo que necesitas ya está en "tu" código y en mi ejemplo.
Valora esta respuesta
Me gusta: Está respuesta es útil y esta claraNo me gusta: Está respuesta no esta clara o no es útil
0
Comentar

Matar dos procesos hijos en C

Publicado por Tom (515 intervenciones) el 04/12/2016 22:27:40
Bueno, perdón, todo, todo no, como puedes suponer, el primer proceso que creas con fork() no puede conocer el pid del siguiente proceso, que aún ni existe ...
Valora esta respuesta
Me gusta: Está respuesta es útil y esta claraNo me gusta: Está respuesta no esta clara o no es útil
0
Comentar

Matar dos procesos hijos en C

Publicado por Katerina (10 intervenciones) el 05/12/2016 00:38:53
He hecho esto, pero no sale.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
#include <stdlib.h>
#include <unistd.h>
#include <stdio.h>
#include <signal.h>
#include <sys/wait.h>
 
pid_t hijo1, hijo2;
 
void tiempo(int sig) {
	printf("Killing childs ...\n");
	kill(hijo1, SIGKILL);
	kill(hijo2, SIGKILL);
}
 
/* */
void funcion() {
	printf("Se ha recibido una señal\n");
}
 
/* */
int main(int argc, char **argv) {
	struct sigaction action;
	sigset_t new_mask, oldmask;
	int exitcode;
 
	action.sa_flags = 0;
	action.sa_handler = funcion;
 
	sigaction(SIGTERM, &action, NULL);
        sigaction(SIGUSR1, &action, NULL);
 
	hijo1 = fork();
	switch(hijo1) {
	case 0:
		   sigfillset(&new_mask);
		   sigdelset(&new_mask, SIGUSR1);
                   sigdelset(&new_mask, SIGTERM);
		   sigsuspend(&new_mask);
	}
 
	hijo2 = fork();
	switch(hijo2) {
	case 0:
		   sigfillset(&new_mask);
		   sigdelset(&new_mask, SIGUSR1);
                   sigdelset(&new_mask, SIGTERM);
		   sigsuspend(&new_mask);
	}
 
        if(pidH1)
           kill(pidH2, SIGUSR1);
 
        if(pidH2)
           kill(pidH1, SIGUSR1);
 
	signal(SIGALRM, tiempo);
	alarm(5);
	wait(&exitcode);
	wait(&exitcode);
}
Valora esta respuesta
Me gusta: Está respuesta es útil y esta claraNo me gusta: Está respuesta no esta clara o no es útil
0
Comentar