es.davy.ai

Preguntas y respuestas de programación confiables

¿Tienes una pregunta?

Si tienes alguna pregunta, puedes hacerla a continuación o ingresar lo que estás buscando.

shmget devuelve un ID diferente para la misma clave.

Hola, he creado un pequeño programa de transferencia de archivos cliente-servidor en Linux. Pero algo extraño está sucediendo. Si inicio primero el cliente y luego el servidor, todo funciona bien. shmget() da el mismo id para la clave proporcionada. Desafortunadamente, si inicio primero el servidor y luego el cliente, obtengo un id diferente en el cliente y no puedo copiar datos.
Estoy usando la bandera IPC_CREAT para unirme a la memoria compartida.

cliente

id=shmget(138134,1,0777|IPC_CREAT);

servidor

id=shmget(138134,1,0777|IPC_CREAT);

Información básica
Básicamente hay un semáforo con tres elementos. Servidor | sem0 | memoria compartida | sem1 | cliente. Sem2 se utiliza cuando el servidor y cliente encuentran EOF. Y copio los datos caracter por caracter. Cliente y servidor tienen las mismas funciones básicas de semáforo y memoria compartida para crear, eliminar, etc. La única diferencia está en el main. Desafortunadamente, el código está en polaco, pero quizás ayude un poco.

main del servidor

utworz<em>nowy</em>semafor();//crear semáforo  
    upd();//crear memoria compartida  
    upa();//unir memoria compartida  
    odlaczenie1=shmctl(pamiec,IPC<em>RMID,0);//marcar la memoria compartida para eliminar (esperando la desconexión)  
    FILE* we = fopen("zrodlo", "r");  
    if (we == NULL)  
    {  
        printf("Error al abrir el archivo de entrada");  
        exit(1);  
    }  
    else  
    {  
        printf("Archivo de entrada abierto\n");  
    }  
    int c;  
    semafor</em>v(0);//abrir la puerta  
    while((c = fgetc(we)) != EOF)  
    {  
        semafor<em>p(0);//cerrar la puerta  
        wstaw(c);  
        semafor</em>v(1);  
    }  
 semafor<em>p(0);  
    wstaw(c);  
    semafor</em>v(1);  
    fclose(we);  
    printf("Archivo fuente cerrado! Esperando señal del consumidor para finalizar la ejecución\$
    semafor<em>p(2);  
    printf("El consumidor ha dejado de copiar. ¡Cerrando programa!\n");  
    odlaczenie2=shmdt(adres);  
    if (odlaczenie1==-1 || odlaczenie2==-1)  
      {  
        printf("Problemas para desconectar la memoria compartida.\n");  
        exit(EXIT</em>FAILURE);  
      }  
    else printf("Memoria compartida desconectada.\n");  
    //odlacz<em>pamiec();  
    exit(EXIT</em>SUCCESS);

main del cliente

utworz<em>nowy</em>semafor();  
    upd();  
    upa();  
    FILE* wy; wy = fopen("wynik", "w");  
    if(wy == NULL)  
    {  
        printf("Error al crear el archivo");  
        exit(1);  
    }  
    else  
    {  
        printf("¡Archivo de resultado creado!\n");  
    }  
    while(1 != 0)  
    {  
         semafor<em>p(1);  
         char c = wez();  
         if(c == EOF)  
         {  
              printf("Fin del archivo. Interrumpiendo el bucle\n");  
              fclose(wy);  
              break;  
         }  
         fputc(c, wy);  
         printf("El consumidor recibió el carácter: %c\n",c);  
         semafor</em>v(0);  
    }  
    semafor<em>v(2);  
    usun</em>semafor();  
    odlaczenie1=shmctl(pamiec,IPC<em>RMID,0);  
    odlaczenie2=shmdt(adres);  
    if (odlaczenie1==-1 || odlaczenie2==-1)  
     {  
        printf("Problemas para desconectar la memoria compartida.\n");  
        exit(EXIT</em>FAILURE);  
     }  
        else printf("Memoria compartida desconectada.\n");  

exit(EXIT_SUCCESS);
“`

Tags:  , ,

Answer

  1. Avatar for davy.ai

    El problema con el programa de transferencia de archivos cliente-servidor parece estar relacionado con el segmento de memoria compartida. Cuando el cliente se lanza primero, crea un segmento de memoria compartida con la clave 138134 usando la función shmget(). El servidor también crea un segmento de memoria compartida con la misma clave, y shmget() devuelve correctamente el ID del segmento existente. Tanto el cliente como el servidor pueden acceder al segmento de memoria compartida y transferir datos con éxito.

    Sin embargo, cuando el servidor se lanza primero y crea el segmento de memoria compartida, el cliente no puede acceder al mismo segmento de memoria compartida utilizando la misma clave. En su lugar, shmget() devuelve un ID diferente para el segmento, lo que evita que el cliente copie datos.

    Basándonos en el código proporcionado, es difícil determinar la causa exacta de este problema. Es posible que el segmento de memoria compartida no se esté limpiando correctamente cuando el servidor se cierra, lo que podría impedir que el cliente acceda al segmento al iniciarse. También es posible que haya una condición de carrera en la que el cliente esté intentando acceder al segmento de memoria compartida antes de que el servidor lo haya creado por completo.

    Puede ser necesaria una investigación y depuración adicionales para identificar y abordar la causa raíz de este problema.

Comments are closed.