#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
Hors ligne