Unix - PROBLEMA AL ELIMINAR UN PROCESO

 
Vista:

PROBLEMA AL ELIMINAR UN PROCESO

Publicado por DANIEL (8 intervenciones) el 31/10/2006 14:01:53
Hola,

Tengo un programa en C que crea varios procesos, , los procesos creados no finalizan se quedan en espera tras ser creados. tras su creacion, compruebo desde elinterprete de comandos ps -e y me muestra la pid ,por ejemplo:

1
2
3
4
5

ya desde el programa , que tiene un menu doy a eliminar procesos e imaginemonos que selecciono el 3 y este 3 lo guardo en opcion y ejecuto kill(opcion,SIGTERM), tras esto
vuelvo al interprete de comando vuelvo hacer un ps -e y me muestra

2
3
4
5

o sea me elimina el 1er proceso no el que yo he introducido, he comprobado todo mil veces, opcion me coge bien el valor......no lo entiendo........................

si alguien sabe que podria ser antes de que enloquezca!!!!

gracias
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

RE:PROBLEMA AL ELIMINAR UN PROCESO

Publicado por Tom (178 intervenciones) el 31/10/2006 14:48:45
Lo único que se me ocurre es que estás matando el proceso con pid 1, no el que tiene pid 3. Deberías hacer una traza de lo que envías realmente a kill().

También depende de cómo estés lanzando esos procesos (¿fork(), clone(), exec(), con threads?)
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

RE:PROBLEMA AL ELIMINAR UN PROCESO

Publicado por daniel (8 intervenciones) el 31/10/2006 16:30:55
hola tom,

te adjunto como creo los procesos:

while (i<N) {


switch ( pid= fork()) {

case -1 :

error("Error de creación proceso hijo");

//Proceso hijo

case 0:


execlp("./calculador","calculador",(char *)0);
error("Error ejecutando calculador");

//Proceso padre

default:

p_calculador[i].id = pid;
sprintf(mensaje,"principal %d creando proceso hijo [%d] : %d",getpid(),i,p_calculador[i].id);
escriure_string(mensaje,"");

} // fin del switch

i++;


}
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

RE:PROBLEMA AL ELIMINAR UN PROCESO

Publicado por Tom (178 intervenciones) el 31/10/2006 18:10:19
while (i<N) {

switch ( pid= fork()) {
case -1 :
error("Error de creación proceso hijo");
//Proceso hijo
break;

case 0:
execlp("./calculador","calculador",(char *)0);
error("Error ejecutando calculador");
break;

//Proceso padre
default:
p_calculador[i].id = pid;
sprintf(mensaje,"principal %d creando proceso hijo [%d] : %d",getpid(),i,p_calculador[i].id);
escriure_string(mensaje,"");
i++;
} // fin del switch
}

Prueba así (parece igual que tu código, pero no lo es).
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

RE:PROBLEMA AL ELIMINAR UN PROCESO

Publicado por daniel (8 intervenciones) el 02/11/2006 21:55:45
HOla,

Antes de nada muchas gracias tom, lo he puesto como me comentas pero me sigue sucediendo lo mismo. pongo la funcion de eliminar el proceso

int eliminar_proceso_integrador(){

int contador,trobat;
int status;





trobat= 0;
contador=0;



while( contador < MAXPROCS && !trobat) {

if (p_calculador[contador].id == id_e){

kill(id_e, SIGTERM);
wait(&status);
p_calculador[contador].id =-1;
trobat =1;

}else{

contador++;
}
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

RE:PROBLEMA AL ELIMINAR UN PROCESO

Publicado por Tom (178 intervenciones) el 03/11/2006 09:16:00
No sé, lo he probado y debería ir bien. Mira este código a ver si ves algo (funciona correctamente en Linux, debería funcionar tb en Solaris).

#include <unistd.h>
#include <stdlib.h>
#include <signal.h>
#include <stdio.h>
#include <sys/types.h>
#include <sys/wait.h>

#define MAX_PROCS 5

/* */
int main(int argc, char *argv[]) {
pid_t procs[5],
pid;
int stat,
i = 0;

while(i < MAX_PROCS) {
switch(procs[i] = fork()) {
case -1:
perror("fork");
break;
case 0:
/* Proceso hijo */
if(execlp("kcalc", "kcalc", 0)) {
perror("execlp");
}
break;
default:
/* Proceso padre */
printf("Nuevo proc: %ld\n", procs[i]);
break;
}
i++;
}
do {
system("ps");
sleep(5);
printf("Se va a matar: %ld\n", procs[--i]);
kill(procs[i], SIGTERM);
pid = wait(&stat);
} while(i);

exit(0);
}
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

RE:PROBLEMA AL ELIMINAR UN PROCESO

Publicado por daniel (8 intervenciones) el 03/11/2006 09:29:30
hola Toma,

Nuevamente muchisimas gracias, adjunto todo el codigo, creo que el problema puede estar en el menú, lo voy a repasar detalladamente, lo pongo por si tú puedes tambien darle un vistazo. y de nuevo te estoy muy agradecido

#include "rutines.h"


/* Variables de parametres segon opcions de menu */
double R=0, S=0; /* Interval Integració*/
int T=0; /* Nombre Trapecis sub-interval Integració*/
int N=0; /* Nombre Processos Integradors */
int ID_E=0;

struct proceso_calculador p_calculador[MAXPROCS];

/* Prototips de les funcions desenvolupades */
int menu();
void inicialitzar(void);
int eliminar_proces_integrador(void);
int crear_processos_integradors(void);
void calcular_integral(void);
void acabar(void);

int menu()
{
int opcio;
char buffer[MAXSTR];


/* escriu menu */
escriure_string("\nMENU:","");
escriure_string(" 1) Crear processos calculadors ","");
escriure_string(" 2) Eliminar procès calculador ","");
escriure_string(" 3) Calcular ","");
escriure_string(" 4) Fi de totes les aplicacions ","");

llegir_string("OPCI� ", buffer);
opcio = atoi(buffer);
while (opcio < 1 || opcio > 4)
{
llegir_string("\n Indiqueu novament l'opci� ", buffer);
opcio=atoi(buffer);
}

/* llegeix el nombre de processos integradors */
if (opcio == 1)
{
do
{
llegir_string ("Introducir el nombre de processos: ", buffer);
N = atoi(buffer);

if ( (N > 5) || (N < 1) )
escriure_string("Nombre de processos incorrecte. ", "");
}
while ((N > 5) || (N < 1));
}

if(opcio== 2)
{

llegir_string("Identificador del procés a eliminar: ", buffer);
ID_E = atoi(buffer);



}

/* llegeix el interval dintegració [r, s] */
if (opcio == 3)
{
do
{
llegir_string("Introduir el inici del interval dintegraci� ", buffer);
R = atof(buffer);

llegir_string("Introduir el final del interval dintegraci� ", buffer);
S = atof(buffer);

if ( R>=S )
escriure_string("Interval d'integraci�incorrecte. ", "");
}
while ( R>=S );

do
{
llegir_string ("Introducir el nombre de trapezis: ", buffer);
T = atoi(buffer);

if ( (T > 100000) || (T < 1) )
escriure_string("Nombre de Trapezis Incorrecte. ", "");
}
while ( (T > 100000) || (T < 1) );
}

return opcio;
}



void inicialitzar(void)
{

int i=0;

for ( i=0; i<MAXPROCS; i++){
p_calculador[i].id= -1;
}




}



int crear_processos_integradors()
{
int i,proces,c;
int trobat;
char mensaje[80];

//Comprobamos que exista algun proceso libre

i = 0;


while (i<N) {


switch (proces = fork()) {

case -1 :

error("Error de creación proceso hijo");

//Proceso hijo
break;

case 0:
trobat =1;
execlp("./calculador","calculador",NULL);
error("Error ejecutando calculador");
break;

//Proceso padre

default:

p_calculador[i].id = proces;
sprintf(mensaje,"principal %d creando proceso hijo [%d] : %d",getpid(),i,p_calculador[i].id);
escriure_string(mensaje,"");
i++;
} // fin del switch

}
return trobat;
}


int eliminar_proces_integrador(){

int i,trobat,eliminar;
int status;
char mensaje[80];

trobat=0;





for ( i=0; i<MAXPROCS; i++){

if( ID_E==p_calculador[i].id){


kill (ID_E,SIGTERM) ;


wait(&status);
p_calculador[i].id=-1;
trobat=1;
}
}



return trobat;





}


/

/
int main(int argc, char* argv[])
{
char miss[80];
float x1,x2;



// Exemple utilitzaciò Macro Funcio Integració (FunInt)
x1=FunInt(1.0);
x2=FunInt(1.5);
sprintf(miss, "Valors funció integració: F(1.0)=%f F(1.5)=%f F(2)=%f.\n",x1,x2,FunInt(2) );
escriure_string(miss,"");

inicialitzar();

for (;;) {
switch (menu()) {
case 1:



if (!crear_processos_integradors())
if (write (2, "Error creando integrador o procesos ya creados\n", strlen("Error creando integrador o procesos ya creados\n")) < 0)
error("En crear Integrador");

break;

case 2:
/* Eliminar Proc� integrador (crida a funci�que ho faci) */
if (!eliminar_proces_integrador())
if (write (2, "Error eliminar integrador\n", strlen("Error eliminar integrador\n")) < 0)
error("En eliminar Integrador");
break;

case 3:
/* Calcular Integral (crida a funci�que ho faci) */
calcular_integral();
break;

case 4:
/* acabar, matant a tots els processos integradors (crida a funci�que ho faci)*/
acabar();
exit(0);

}
}
}
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

RE:PROBLEMA AL ELIMINAR UN PROCESO

Publicado por daniel (8 intervenciones) el 03/11/2006 09:32:12
Y el rutines.h

#include <errno.h>
#include <string.h>
#include <signal.h>
#include <unistd.h>
#include <math.h>
#include <stdio.h>
#include <time.h>
#include <sys/types.h>
#include <stdlib.h>

#define MAXSTR 100
#define MAXPROCS 5

#define CERT 1
#define FALS 0

#define FunInt(x) (2*(x)*(sin(x)+1)) // Funció Integració

struct proceso_calculador{
int pipe[2];
int id;
};

/* Prototips de les funcions */
void error(char *miss);
void treu_missatge(char *miss);
void llegir_string(char *miss, char *addr);
void escriure_string(char *miss, char *buffer);

/******************************************************************************/
/* Nom de la funcio: error */
/* Descripcio: Escriu missatge d'error i acaba l'execucio del programa */
/* Parametres: El missatge d'error (miss) */
/******************************************************************************/

void error(char *miss)
{
write(2, miss, strlen(miss));
write(2, "\n", 1);
write(2, strerror(errno), strlen(strerror(errno)));
exit(1);
}

/******************************************************************************/
/* Nom de la funcio: tre_missatge */
/* Descripcio: Escriu missatge per la sortida estàndard d'error */
/* Parametres: El missatge */
/******************************************************************************/

void treu_missatge(char *miss)
{
write(2, miss, strlen(miss));
write(2, "\n", 1);
}


/*****************************************************************************/
/* Nom de la funcio: llegir_string */
/* Descripcio: Escriu un missatge que es passa com parametre i guarda */
/* a memoria el que llegeix de l'entrada estandar */
/* Parametres: El missatge explicatiu (miss) i l'adreca de memoria on */
/* guardar la lectura */
/*****************************************************************************/

void llegir_string(char *miss, char *addr)
{
int n;

if (write(1, miss, strlen(miss)) < 0)
error("error escrivint");
if ((n = read(0, addr, MAXSTR)) < 0)
error("error llegint");
if (addr[n - 1] != '\n')
error("Hauria de ser salt de linia");
addr[n - 1] = 0; /* Posem la marca de final d'string */
}

/******************************************************************************/
/* Nom de la funcio: escriure_string */
/* Descripcio: Escriu un missatge explicatiu i escriu un string */
/* de memoria per sortida standard */
/* Parametres: El missatge explicatiu (miss) i l'adreca de memoria on */
/* es l'string */
/******************************************************************************/

void escriure_string(char *miss, char *buffer)
{
if (write(1, miss, strlen(miss)) < 0)
error("write miss");
if (write(1, " ", 1) < 0)
error("write");
if (write(1, buffer, strlen(buffer)) < 0)
error("write buffer");
if (write(1, "\n", 1) < 0)
error("write");
}
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

RE:PROBLEMA AL ELIMINAR UN PROCESO

Publicado por Tom (178 intervenciones) el 03/11/2006 13:06:39
Lo siento, chico, a mí me funciona.
Sólo he creado las funciones
void calcular_integral() {
}
void acabar() {
}
para poder compilar, y un shell script ./calculador para poder ejecutar.

Y todo va bien, lanzo tres procesos y luego los elimino uno a uno sin problemas.

Te recomiendo que pongas una traza cuando vas a eliminar el proceso y que compruebes kill:

if (ID_E == p_calculador[i].id) {

// TRAZA
printf("Trato de matar el proceso: %ld\n", ID_E);
//
kill(ID_E, SIGTERM);

// TRAZA
printf("Matado: %ld\n", wait(&status));
p_calculador[i].id = -1;
trobat = 1;
}
}

Y, si puedes, cambia los tipos de ID_E y p_calculador[].id de int a pid_t (por coherencia y por si acaso)
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

RE:PROBLEMA AL ELIMINAR UN PROCESO

Publicado por daniel (8 intervenciones) el 03/11/2006 14:01:22
Muchisimas gracias Tom, cambiare el tipo y pondre trazas,......

te agradezco muchisimo tu ayuda
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