Contenu | Rechercher | Menus

Annonce

Si vous avez des soucis pour rester connecté, déconnectez-vous puis reconnectez-vous depuis ce lien en cochant la case
Me connecter automatiquement lors de mes prochaines visites.

À propos de l'équipe du forum.

#1 Le 21/09/2007, à 08:53

CasseTaTele

[How-to] Libérer des segments de mémoires partagé

Bonjour,

Lorsqu'un programme ne se termine pas correctement, il arrive que des instances crée ne soient pas supprimées. C'est souvent le cas lorsqu'en programmant on teste des programmes qui se terminent par 'segmentation fault' ou autre...
Pour libérer ces segments, il existe deux commandes bien pratique :

ipcs -m
ipcrm -m [shmid]

c.f. : http://www.esinsa.unice.fr/~vig/ESINSA4/IPC/node8.html

Cependant c'est assez galère, car il faut repérer le numéro [shmid] de chacun des segments avec la commande ipcs -m puis libérer chacun de ces segments... tous les segments ne peuvent pas être libérés, seul ceux qui ne sont plus utilisés semblent pouvoir l'être (a confirmer ?)

Pour se simplifier la vie, voici donc un petit prog qui liste puis libère tous les segments mémoire de l'utilisateur qui lance le prog:

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

int main( int argc, char** argv )
{
   char command[ 20000 ];
   char temp[ 100 ];
   char suite[255];
   char buffer[ 256 ];
   char utilisateur[ 1024 ];

   int tmp, num;
   int i;
   FILE* fic;

	// Recupere le nom de l'utilisateur
   sprintf( command, "whoami > /tmp/check_id" );
   if( system( command ) == -1 )
   {
		printf("Erreur dans la commande whoami > /tmp/check_id\n"); 	fflush(stdout);
		return (1);
	}

	fic = fopen( "/tmp/check_id", "r" );
	if( fic != NULL )
	{
		if (fgets( buffer, 255, fic )!=NULL)
		{
		//	printf("buffer=<%s>\n", buffer); 	fflush(stdout);
			strncpy( utilisateur, buffer, strlen(buffer)-1);
			printf("Retire la mémoire partagée de l'utilisateur <%s>\n", utilisateur); 	fflush(stdout);
		}
		else
		{
			printf("Erreur id utilisateur mal recupere dans LibererMemoirePartagee()\n");			fflush(stdout);
			return(1);
		}
	}
	else
	{
		printf("Erreur de lecture du fichier /tmp/check_id\n"); 	fflush(stdout);
		return (1);
	}


   // Recherche les segments de mémoire partagées mal libérées pour l'utilisateur
   sprintf( command, "ipcs -m | grep %s > /tmp/check_ipcm\n", utilisateur );
   //	printf(command); fflush(stdout);

   if( system( command ) == -1 )
   {
      fprintf( stderr, "clean_ipcm; erreur dans ipcs\n" );
      return( 1 );
   }
   else
   {
      if( ( fic = fopen( "/tmp/check_ipcm", "r" ) ) == NULL )
      {
			fprintf( stderr, "clean_ipcm; erreur dans fopen\n" );
			return( 1 );
      }
      
      command[ 0 ] = '\0';

      //Saut de trois lignes
		// fgets( buffer, 255, fic );
		// fgets( buffer, 255, fic );
		// fgets( buffer, 255, fic );


      while( fgets( buffer, 255, fic ) != NULL )
      {
			for (i = 11; i < strlen(buffer) ; i++) suite[i-11]= buffer[i];
    
			if( sscanf( suite, "%d ", &num ) == 1 )
			{	  
				sprintf(command, "ipcrm -m %d ", num );
				printf( ">> %s\n",command );
	    
				if( system( command ) == -1 )
				{
					fprintf( stderr, "clean_ipcm; erreur dans ipcrm\n" );
					return( 1 );
				}
			}
      }
     

      sprintf( command, "rm /tmp/check_ipcm" );
      if( system( command ) == -1 )
		{
			fprintf( stderr, "clean_ipcm; erreur dans rm /tmp/check_ipcm\n" );
			return( 1 );
		}

      sprintf( command, "rm /tmp/check_id" );
      if( system( command ) == -1 )
		{
			fprintf( stderr, "clean_ipcm; erreur dans rm /tmp/check_id\n" );
			return( 1 );
		}
      else
		{
//			sprintf( command, "ipcs -m |grep %s", utilisateur);
//			system( command );
			return( 0 );
		}

	}

	return (0);
}

copiez ce code dans un fichier clean_ipcm.c
puis compilez avec la commande suivante:

gcc -o clean_ipcm clean_ipcm.c

Il ne vous reste plus qu'à déplacer le prog dans un répertoire du path, par exemple:

sudo mv clean_ipcm /usr/bin

si vous programmez souvent, et que vous avez l'habitude de manipuler des gros fichiers genre vidéo vous serez surpris de pouvoir libérer ainsi plusieurs méga de RAM...

a+

Hors ligne

#2 Le 21/09/2007, à 10:05

reeth

Re : [How-to] Libérer des segments de mémoires partagé

Merci bien pour ce programme wink

Hors ligne