User Tag List

Página 1 de 4 1234 ÚltimoÚltimo
Resultados 1 al 15 de 46

Tema: Linux y programación en C: ¿cómo modifico el nombre de un proceso "desde dentro"?

  1. #1

    Fecha de ingreso
    May 2004
    Mensajes
    1,535
    Mencionado
    8 Post(s)
    Tagged
    0 Tema(s)
    Agradecer Thanks Given 
    75
    Agradecer Thanks Received 
    5
    Thanked in
    Agradecido 5 veces en [ARG:2 UNDEFINED] posts

    Linux y programación en C: ¿cómo modifico el nombre de un proceso "desde dentro"?

    Hola gente:

    En esto de Linux soy practicamente por completo autodidacta, y por tanto, algunas cosas se me escapan. Por eso no he sabido muy bien cómo explicar mi duda en el título. Os comento lo que quiero hacer, cómo lo tengo hecho hasta ahora, y mi duda, de tal manera que si me echáis por tierra lo que ya tengo hecho en pro de una mejor idea, yo la acepto.

    Lo que quiero es que mediante un programa (llamémosle de control, al que mando comandos por una tubería no bloqueante de sólo lectura), ejecute otros en función de esos comandos.
    - Por una parte lanzo unos en cuyo nombre llevan un identificador (un número al final) y que por tanto a la hora de matar (también por medio de otro comando) sólo he de buscar el que tenga tal nombre y matarlo.
    - Por otra tengo otro que lanzo tantas veces como se le pida, al que se le manda un argumento (que define la IP a la que se conectará debido a que es un cliente de una estructura de sockets, pero digamos que esto es secundario). Es aquí donde surge mi problemilla: a la hora de matarlo, si lo busco por nombre, como lo lance las veces que lo lance, por mucho que el argumento sea distinto, el nombre será igual, así que cuando busque los PID para cepillármelo, me los cepillaré todos. Entonces pensaba en si se podría añadir en el "nombre de ejecución" (no sé cómo se llama, el nombre que aparece tras un ps) al final, por ejemplo, el agumento. Ejemplo:
    Código:
    ./programa 23
    Que en un ps, me dijese:
    Código:
    1567 (bueno, lo que diga, no tengo la máquina UNIX ahora) programa23
    en lugar de:
    Código:
    1567 (bueno, lo que diga, no tengo la máquina UNIX ahora) programa
    Y bueno, eso, si véis que lo que tengo hecho, se puede hacer mejor de otra manera, o queréis más información, o lo que sea, os agradeceré infinito que me lo comentéis.

    Molto grazie de antemano.
    Con permiso de xzakox:

  2. #2

    Fecha de ingreso
    Mar 2007
    Ubicación
    Barna
    Mensajes
    10,347
    Mencionado
    93 Post(s)
    Tagged
    0 Tema(s)
    Agradecer Thanks Given 
    371
    Agradecer Thanks Received 
    1,787
    Thanked in
    Agradecido 945 veces en [ARG:2 UNDEFINED] posts
    Diría que lo mejor es que registres el PID de cada proceso al inicio con la función getpid(), y no que lo busques cuando quieras matarlo porque como dices es difícil de distinguir Otra opción es que inicies los procesos desde un programa que controles tú, y así al iniciarlos sabrás sus PIDs sin tener que buscarlos después.

    Diría que el nombre del proceso no se puede cambiar en tiempo de ejecución porque esa es información interna que mantiene el kernel.

    Ah, pues sí que hay una forma, aunque confieso que me ha parecido tan compleja que no la he leido en detalle http://stupefydeveloper.blogspot.com...cess-name.html
    Última edición por juanvvc; 23/04/2010 a las 16:02

  3. #3

    Fecha de ingreso
    May 2004
    Mensajes
    1,535
    Mencionado
    8 Post(s)
    Tagged
    0 Tema(s)
    Agradecer Thanks Given 
    75
    Agradecer Thanks Received 
    5
    Thanked in
    Agradecido 5 veces en [ARG:2 UNDEFINED] posts
    Cita Iniciado por juanvvc Ver mensaje
    Diría que lo mejor es que registres el PID de cada proceso al inicio con la función getpid(), y no que lo busques cuando quieras matarlo porque como dices es difícil de distinguir Otra opción es que inicies los procesos desde un programa que controles tú, y así al iniciarlos sabrás sus PIDs sin tener que buscarlos después.
    Sí, el programa que lanza los programas es mío también, así que eso sí que lo podría hacer, sería un cambio en la filosofía, y que yo creo que me evitaría las movidas que me hago ahora para matar los malditos procesos, que a veces no me deja ni ná. Te agradecería que me ampliases un poco la info de cómo coger el PID a la hora de iniciarlo

    Cita Iniciado por juanvvc Ver mensaje
    Diría que el nombre del proceso no se puede cambiar en tiempo de ejecución porque esa es información interna que mantiene el kernel.

    Ah, pues sí que hay una forma, aunque confieso que me ha parecido tan compleja que no la he leido en detalle http://stupefydeveloper.blogspot.com...cess-name.html
    Sí, creo que mejor paso de cambiar el nombre
    Qué maldita locura, jaja.
    Con permiso de xzakox:

  4. #4

    Fecha de ingreso
    Mar 2007
    Ubicación
    Barna
    Mensajes
    10,347
    Mencionado
    93 Post(s)
    Tagged
    0 Tema(s)
    Agradecer Thanks Given 
    371
    Agradecer Thanks Received 
    1,787
    Thanked in
    Agradecido 945 veces en [ARG:2 UNDEFINED] posts
    Tu programa controlador sería algo así (ojo que no lo he probado):

    Código:
    #define NUM_PROCESS 5
    int main(){
       int* pids=int[NUM_PROCESS];  // aquí guardaremos los PIDs
    
      for(int i=0; i<NUM_PROCESS; i++){
        pids[i]=fork(); // Llamada a fork! Ahora tenemos dos programas ejecutándose a la vez, padre e hijo
        if(pids[i]==0){
          // somos el hijo: nos cambiamos por el nuevo programa
          execl("./programa", "./programa","argumento1","argumento2",(char *)0);
          // ya deberíamos ser el nuevo programa, así que si seguimos aquí es por un error
          printf("Error al ejecutar el programa\n");
          // Los hijos nunca deberían salir de este if, así que por si alguno se escapa lo terminamos
          exit(1);  
        }else if(pids[i]<0){
          // somos el padre y hemos fallado al crear el hijo.
          printf("Error en el fork()");
        }else{
          // Somos el padre y todo fue bien:
          printf("He parido un nuevo retoño con PID=%d\n", pids[i]);
        }
      }
    
      // Resto de código del controlador una vez que haya creado a sus hijos.
      // Recuerda que hemos tenido cuidado para que los hijos nunca lleguen aquí
      // Recuerda que los PIDs están en el array pids[]
      // Y finalmente, recuerda que puedes esperar a que los hijos acaben con wait() y waitpid()
      patata();
    
    }
    Última edición por juanvvc; 23/04/2010 a las 16:34

  5. #5

    Fecha de ingreso
    May 2004
    Mensajes
    1,535
    Mencionado
    8 Post(s)
    Tagged
    0 Tema(s)
    Agradecer Thanks Given 
    75
    Agradecer Thanks Received 
    5
    Thanked in
    Agradecido 5 veces en [ARG:2 UNDEFINED] posts
    Mil gracias, juanvvc, a ver si luego le echo unas pruebas. Tengo que parir los programas en función de lo que me llegue por una tubería, pero bueno, yo creo que fusionando lo que me das y lo que tengo puedo llegar a algo

    Si me surge cualquier cosilla lo comento.

    Un saludete
    Con permiso de xzakox:

  6. #6

    Fecha de ingreso
    Mar 2004
    Mensajes
    7,733
    Mencionado
    14 Post(s)
    Tagged
    0 Tema(s)
    Agradecer Thanks Given 
    6
    Agradecer Thanks Received 
    72
    Thanked in
    Agradecido 30 veces en [ARG:2 UNDEFINED] posts
    argv[0] es el nombre del proceso. Cámbialo y listo.

    Propeller

  7. #7

    Fecha de ingreso
    May 2004
    Mensajes
    1,535
    Mencionado
    8 Post(s)
    Tagged
    0 Tema(s)
    Agradecer Thanks Given 
    75
    Agradecer Thanks Received 
    5
    Thanked in
    Agradecido 5 veces en [ARG:2 UNDEFINED] posts
    Cita Iniciado por Propeller Ver mensaje
    argv[0] es el nombre del proceso. Cámbialo y listo.

    Propeller
    Ostras, no había caído en el detalle. Sólo que no sabía que cambiando el nombre a argv[0] afectaba (vamos, si me llegan a preguntar hubiera jurado que no hace caso y punto, jajaja).

    Bien, probaré eso, aunque es probable que reestructure todo y acabe moviéndome por PID más que por nombre de proceso.

    De todas maneras, muchísimas gracias por el comentario, Propeller.

    Un saludo
    Con permiso de xzakox:

  8. #8

    Fecha de ingreso
    Mar 2007
    Ubicación
    Barna
    Mensajes
    10,347
    Mencionado
    93 Post(s)
    Tagged
    0 Tema(s)
    Agradecer Thanks Given 
    371
    Agradecer Thanks Received 
    1,787
    Thanked in
    Agradecido 945 veces en [ARG:2 UNDEFINED] posts
    Pero como bien sabe propeller, eso no funciona más que dentro del programa y además corres el riesgo de jorobar toda la cabecera como el nuevo nombre tenga más letras que el antiguo.

    De todas formas lo acabo de probar porsiaca, y ps no hace caso de un nombre cambiado por argv[0]

    (propeller, tienes la oportunidad de vengarte en el hilo de las estafas )
    Última edición por juanvvc; 23/04/2010 a las 17:27

  9. #9

    Fecha de ingreso
    May 2004
    Mensajes
    1,535
    Mencionado
    8 Post(s)
    Tagged
    0 Tema(s)
    Agradecer Thanks Given 
    75
    Agradecer Thanks Received 
    5
    Thanked in
    Agradecido 5 veces en [ARG:2 UNDEFINED] posts
    Cita Iniciado por juanvvc Ver mensaje
    Pero como bien sabe propeller, eso no funciona más que dentro del programa y además corres el riesgo de jorobar toda la cabecera como el nuevo nombre tenga más letras que el antiguo.

    De todas formas lo acabo de probar porsiaca, y ps no hace caso de un nombre cambiado por argv[0]

    (propeller, tienes la oportunidad de vengarte en el hilo de las estafas )
    Jajaja, ok, gracias por ahorrarme el currelo, juan

    Nada, a ver si luego puedo probar lo de los execlv, fork, getpid y esas cosucas.
    Con permiso de xzakox:

  10. #10

    Fecha de ingreso
    Mar 2004
    Mensajes
    7,733
    Mencionado
    14 Post(s)
    Tagged
    0 Tema(s)
    Agradecer Thanks Given 
    6
    Agradecer Thanks Received 
    72
    Thanked in
    Agradecido 30 veces en [ARG:2 UNDEFINED] posts
    Hombre, si usas el modificador 'u' para el ps, ves la modificación (al menos en Linux).

    Propeller

  11. #11

    Fecha de ingreso
    Mar 2007
    Ubicación
    Barna
    Mensajes
    10,347
    Mencionado
    93 Post(s)
    Tagged
    0 Tema(s)
    Agradecer Thanks Given 
    371
    Agradecer Thanks Received 
    1,787
    Thanked in
    Agradecido 945 veces en [ARG:2 UNDEFINED] posts
    Esta es la salida de uname -a (Debian sid): Linux currito 2.6.32-3-amd64 #1 SMP Wed Feb 24 18:07:42 UTC 2010 x86_64 GNU/Linux

    Este es el programa que he probado, compilado con gcc -o prueba prueba.c

    Código:
    #include <stdio.h>
    int main(int argc, char** argv){
    	printf("Nombre del programa %s\n", argv[0]);
    	argv[0]="hola";
    	printf("Nombre del programa %s\n", argv[0]);
    	while(1);
    }
    Y esta es la salida del comando "ps u" mientras está ejecutándose el anterior:

    Código:
    USER       PID %CPU %MEM    VSZ   RSS TTY      STAT START   TIME COMMAND
    juanvi    4360  0.0  0.1  21536  4596 pts/2    Ss   18:13   0:00 /bin/bash
    juanvi    4447 99.9  0.0   3652   404 pts/2    R+   18:13   5:54 ./prueba
    juanvi    4531  6.0  0.1  21544  4608 pts/1    Ss   18:18   0:00 /bin/bash
    juanvi    4618  0.0  0.0  16076  1124 pts/1    R+   18:18   0:00 ps u
    ¿Puede ser que no haya entendido tu propuesta?

  12. #12

    Fecha de ingreso
    Mar 2007
    Ubicación
    Barna
    Mensajes
    10,347
    Mencionado
    93 Post(s)
    Tagged
    0 Tema(s)
    Agradecer Thanks Given 
    371
    Agradecer Thanks Received 
    1,787
    Thanked in
    Agradecido 945 veces en [ARG:2 UNDEFINED] posts
    Pues sí, id6490, tienes toda la razón. No sé porqué había pensado que strcpy() no era necesario, pero es que, claro, queremos que argv[0] siga apuntando a donde estaba apuntando.

    3L_S4N70, te confirmo que como dicen con argv[0] se puede cambiar el nombre de un programa si usas strcpy, y al menos ps lo lista con el nuevo nombre. Bueno, en realidad también hay que cambiar la cabecera para que sea consciente del nuevo número de caracteres del nombre, pero si usas un nombre con el mismo número no parece que vayas a tener problemas.

  13. #13

    Fecha de ingreso
    Apr 2010
    Ubicación
    JULY CITY
    Mensajes
    1,524
    Mencionado
    2 Post(s)
    Tagged
    0 Tema(s)
    Agradecer Thanks Given 
    342
    Agradecer Thanks Received 
    99
    Thanked in
    Agradecido 63 veces en [ARG:2 UNDEFINED] posts
    una cosa para controlar el reconocimiento de la muerte de procesos me imagino que tendrás algun manejador de señales como este o parecido, no?

    /*Tratamiento de la señal SIGTERM*/
    void manejador_SIGTERM(int sig)
    {
    int error;
    do
    {
    error = wait3(NULL,WNOHANG|WUNTRACED,NULL);
    }while(error == ERROR || errno == EINTR);

    }//fin de la funcion

    lo digo porque si no gestionas bien la señal sigterm cuando matas un proceso puedes tener problemas.
    Última edición por tSuKiYoMi; 02/11/2011 a las 10:07

  14. #14

    Fecha de ingreso
    May 2004
    Mensajes
    1,535
    Mencionado
    8 Post(s)
    Tagged
    0 Tema(s)
    Agradecer Thanks Given 
    75
    Agradecer Thanks Received 
    5
    Thanked in
    Agradecido 5 veces en [ARG:2 UNDEFINED] posts
    Cita Iniciado por juanvvc Ver mensaje
    Pues sí, id6490, tienes toda la razón. No sé porqué había pensado que strcpy() no era necesario, pero es que, claro, queremos que argv[0] siga apuntando a donde estaba apuntando.

    3L_S4N70, te confirmo que como dicen con argv[0] se puede cambiar el nombre de un programa si usas strcpy, y al menos ps lo lista con el nuevo nombre. Bueno, en realidad también hay que cambiar la cabecera para que sea consciente del nuevo número de caracteres del nombre, pero si usas un nombre con el mismo número no parece que vayas a tener problemas.
    Bueno, el tema es que a mi me interesa que el nombre crezca, luego me tocaría andar metiendo mano en la cabecera, así que me tiraré al tema de generar procesos hijos y tal (a ver cómo me las arreglo).

    Cita Iniciado por tSuKiYoMi Ver mensaje
    una cosa para controlar el reconocimiento de la muerte de procesos me imagino que tendrás algun manejador de señales como este o parecido, no?

    /*Tratamiento de la señal SIGTERM*/
    void manejador_SIGTERM(int sig)
    {
    int error;
    do
    {
    error = wait3(NULL,WNOHANG|WUNTRACED,NULL);
    }while(error == ERROR || errno == EINTR);

    }//fin de la funcion

    lo digo porque si no gestionas bien la señal sigterm cuando matas un proceso puedes tener problemas.
    Ehm... pues no. Como comentaba al principio, estoy bastante en pañales en estos temas, entonces me has pillado completamente out. Hasta ahora, y os ruego me indiquéis la mejor manera, lo que hacía era cascar con un system() un kill a todos los procesos con el nombre que le indicase, pero muchas veces casca, o ni funciona, y no se cepilla los procesos.
    Con permiso de xzakox:

  15. #15

    Fecha de ingreso
    Apr 2010
    Ubicación
    JULY CITY
    Mensajes
    1,524
    Mencionado
    2 Post(s)
    Tagged
    0 Tema(s)
    Agradecer Thanks Given 
    342
    Agradecer Thanks Received 
    99
    Thanked in
    Agradecido 63 veces en [ARG:2 UNDEFINED] posts
    para matar procesos puedes usar la función:


    kill(pid_proceso ,señal);

    KILL no sirve para matar procesos de forma explicita, sino para enviar señales a procesos, por tanto si quieres terminar con alguno (martarlo en la jerga) debes ejecutar:

    kill(pid_proceso ,SIGTERM);, resulta que en algunas ocasiones cuando le envias esta señal de terminación al proceso este puede estar terminando de ejecutar algunas instrucciones por lo que no termina definitivamente hasta que acaba dichas instrucciones, sin embargo la señal la sigue recibiendo, una vez acabado si el proceso padre que lo creo no reconoce su "muerte" este proceso se queda en lo que se denomina estado "ZOMBI" es decir la PCB (PROCESS CONTROL BLOCK) del proceso sigue exsitiendo con todos sus descriptores de fichero abiertos (incluidos los sockets que son tmb despcriptores pero especiales ya que se encargan de la comuninicación entre maquinas) lo que implica que consume memoria de forma innecesaria. Por tanto necesitas crearte un manejador para que el proceso padre reconozca la muerte de sus hijos. Como puedes ver en el código que te ponía antes esto sea hace con las funciones de la familia WAIT. Yo te he puesto wait3 que es la que suelo usar yo, pero si te vas al MAN y buscas Wait te vienen todas las funciones de dicha familia y el significado de las constantes que puedes usar.

    Otra recomendación que te hago es que te leas el MAN de SIGNAL y de KILL. Y tmb que si vas a lanzar otras señales que no sean SIGTERM como por ejemplo SIGINT,SIGCHLD, SIGUSR1, SIGUSR2, u otras te crees un manejador explicito para cada una de ellas, porque es la forma más comoda y segura de hacer las cosas bien.

    Otra duda que tengo con tu programa es si los procesos que crean comparten variables o ficheros o ke????, si es esí los mismo te conviene crear un espacio de memoria común entre ellos para poder compartir descriptores de ficheros y de sockets de forma más sencilla y amena. PAra hacerlo en ese caso necesitaras usar la función:

    mmap()

    si es tu caso y vas compartir memoria entre porcesos tmb te recomiendo que te mires la documentación en MAN asociada ha esta función. De todas formas seguro que buscando en google encuentras ejemplos que te pueden aclarar más aun las cosas que te comento.

Página 1 de 4 1234 ÚltimoÚltimo

Permisos de publicación

  • No puedes crear nuevos temas
  • No puedes responder temas
  • No puedes subir archivos adjuntos
  • No puedes editar tus mensajes
  •