Vous êtes sur la page 1sur 4

/**** Creation d'une zone de mmoire interne partage (shm ) **********/

Les IPC Systeme V

#define SHMEM_SIZE 0xff


#define SHMEM_RIGHTS 0x01ff
/* dimension de la zone : 256 octets */
/* droits daccs dans la zone de mmoire partage: 1ff */
int main (int argc, char ** argv) {
/* l'identificateur externe (key) de la zone est un nombre entier*/
int key ; int shm_id ; char * pnl ;int i;
if (argc<2)
exit(1);
key = atoi(argv[1]) ;

La mmoire partage (shm)


Examples

/* creation de la zone commune */


shm_id = shmget(key, SHMEM_SIZE, IPC_CREAT|IPC_EXCL|SHMEM_RIGHTS);
if (shm_id != -1) {
/* attachement la zone de mmoire partage */
pnl = shmat(shm_id, 0, SHMEM_RIGHTS) ;
/* initialisation avec 0 de la zone */
for (i=0;i<SHMEM_SIZE;i++)
pnl[i]='\0' ;
}
else
printf(" Erreur :%d \n",ipc_result);
exit(0) ;
1

/************** Ecriture dans une zone partaje *******************/


#define SHMEM_SIZE 0xff
#define SHMEM_RIGHTS 0x01ff

/****** Supprimmer une zone de mmoire interne partage *********/


#include <stdlib.h>
#include <sys/ipc.h>
#include <sys/shm.h>
#define SHMEM_SIZE 0xff
#define SHMEM_RIGHTS 0x01ff
/* dimension de la zone : 256 octets */
/* droits d'accs dans la zone de mmore partge: 1ff */
int main (int argc, char ** argv) {
/* l'identificateur externe (key) de la zone est un nombre
entier donn en paramtre */
int key ; int shm_id , shm_del ;
if (argc<2)
exit(1);
key = atoi(argv[1]) ;
shm_id = shmget(key, SHMEM_SIZE, SHMEM_RIGHTS) ;
if ((shm_del = shmctl (shm_id , IPC_RMID, 0 )) != -1)
printf ("La zone partagee %d a ete suprimee\n",key) ;
else
printf ("Imposible de supprimer zone %d \n", key) ;
exit(0) ;
}

int main (int argc, char ** argv) {


long i , temp ; long * ptz ; int p1 ;
int key, shm_id ;
if (argc<2)
exit(1) ;
key = atoi(argv[1]) ;
shm_id = shmget(key, SHMEM_SIZE, SHMEM_RIGHTS) ;
ptz = (long *) shmat(shm_id, 0, SHMEM_RIGHTS) ;
p1 = fork() ;
for(i=0 ; i<10000000 ; i++) {
(*ptz)++ ;
// temp = * ptz;
// temp ++ ;
// * ptz = temp ;
}
printf("\n Arret processus pid = %d\n\n", getpid()) ;
exit(0) ;
3

/************ Ecriture dans une zone de mmoire partage : 4 processus fils *************/
int main (int argc, char ** argv) {
long i, k, temp; long * ptz ; int p1,p2,p3,p4, key, shm_id ;
key = atoi(argv[1]) ;
shm_id = shmget(key, SHMEM_SIZE, SHMEM_RIGHTS) ;
ptz = (long *) shmat(shm_id, 0, SHMEM_RIGHTS) ;
if ((p1 = fork()) == 0) {
for(i=0;i<10000000;i++) {
temp = *ptz ; temp ++ ; * ptz = temp ; //(*ptz) ++ ;
}
exit(0) ;
}
if ((p2 = fork()) == 0) {
for(i=0;i<10000000;i++) {
temp = *ptz ; temp ++ ; * ptz = temp ; //(*ptz) ++ ;
}
exit(0) ;
}
if ((p3 = fork()) == 0) {
for(i=0;i<10000000;i++) {
temp = *ptz ; temp ++ ; * ptz = temp ; //(*ptz) ++ ;
}
exit(0) ;
}
if ((p4 = fork()) == 0) {
for(i=0;i<10000000;i++) {
temp = *ptz ; temp ++ ; * ptz = temp ; //(*ptz) ++ ;
}
exit(0) ;
}
printf("\n Arret processus pid = %d\n\n", getpid()) ;
exit(0) ;
5
}

/*********** Ecriture dans la zone partage : caractres A , B, C , D *********************/


int main (int argc, char ** argv) {
long i ; int key, shm_id ; char alf[ ] ="ABCD" ;
char * ptz ; char * ptzi ; int p1, p2, p3, p4, k ; long kj ;
key = atoi(argv[1]) ;
shm_id = shmget(key, SHMEM_SIZE, SHMEM_RIGHTS) ;
ptz = (char *) shmat(shm_id, 0, SHMEM_RIGHTS) ;
ptzi = ptz ;
if ((p1 = fork()) == 0) {
for(i=0; i<100000; i++) {
ptz = ptzi ;
for(k=0 ; k < 255 ; k++) {
for(kj=0; kj<20000000; kj++);
* ptz = alf[0] ;
ptz ++ ;
}
}
exit(1) ;
}
/* */
p4 = fork() ;
if (p4 == 0) {
for(i=0;i<100000;i++) {
ptz = ptzi ;
for(k=0 ; k < 255 ; k++) {
for(kj=0; kj<20000000; kj++);
* ptz = alf[2] ;
ptz ++ ;
}
}
exit(1) ;
}
exit(0) ;
7
}

/******** Lecture d'une zone de mmoire partage ***************/


#include
#define SHMEM_SIZE 0xff
#define SHMEM_RIGHTS 0x01ff
int main(int argc, char ** argv){
long * ptz ;
int shm_id, key ;
if (argc<2)
exit(1) ;
key = atoi(argv[1]) ;
shm_id = shmget(key, SHMEM_SIZE, SHMEM_RIGHTS) ;
ptz = (long *) shmat(shm_id,0,SHMEM_RIGHTS) ;
printf("\n Valeur trouvee dans la zone: %d\n",* ptz);
exit(0) ;
}

Crible dEratostne
Rappel : le crible dEratostne est un algorithme
simple qui permet de dterminer les nombres
premiers. Etant donn un tableau dentiers de 1 N, il
sagit de parcourir ce tableau et dliminer chaque
passage les multiples du premier nombre. On passe
ensuite au nombre suivant (qui est premier !) et on
limine ses multiples
Remarque : Eratostne (v. 276-v. 194 av. J.-C.), mathmaticien,
astronome, gographe et pote grec qui mesura la circonfrence
de la Terre avec une surprenante prcision en dterminant
astronomiquement la diffrence de latitude entre les cits de
Syne (aujourd'hui Assouan) et d'Alexandrie, en gypte.
8

Crible dEratostne

Crible dEratostne

Example

Dans notre version, nous allons utiliser un segment de mmoire


partage afin d'crire une version de cet algorithme. Ce segment
contient un tableau de n entiers, tous initialiss de 1 n au dpart
(tous les entiers sont potentiellement des nombres premiers).
3

10

11

...
1

t[0] t[1]

11

11

t[2] t[3] t[4] t[5] t[6] t[7] t[8]

10

11

...

t[9] t[10]

...
Ensuite le programme principal - crible_v1.c - devra raliser les
liminations des multiples en lanant plusieurs fois (de manire
rcursive) le programme secondaire multiple_v1.c capable de
supprimer dans ce tableau tous les multiples du dernier nombre
premier trouv.

...

Crible dEratostne

10

/*** crible d'eratostene : programme crible_v1.c ****/


/* include <sys/types.h> . . . . . */

Exercice :

/* variables en global pour la fonction fin


key_t cle ; /* cle pour les ipc */
int *t ;
/* adresse du tableau t */
int n ;

1) Ecrire un programme principal crible_v1.c prenant en


paramtre n , qui cre le tableau, l'initialise et lance le premier
programme secondaire avec comme paramtre 2 (on limine
tous les multiples de 2).

*/

void erreur(char *mess){


write(2,mess, strlen(mess));
exit(-1);
}

Lorsque le crible est termin, c'est le programme principal qui


affiche le rsultat.
2) Ecrire le programme secondaire multiples_v1.c qui permet
d'liminer les multiples du nombre pass en paramtre, et qui
avant cela cre lui aussi un programme secondaire pour liminer
les multiples du nombre premier suivant.

void fin (int sig) {


int i; char c;
printf("c'est fini! \n") ;
for (i=0 ; i< n ; i++)
if(t[i])
printf("%d ", t[i]) ;
printf("\n") ;
}

Par exemple multiples 2 lancera multiples 3 qui lancera multiples


5 qui lancera multiples 7 ...

11

12

main (int argc , char **argv) {

main (int argc , char **argv) {


int i ; char c; int shmid ; /* id zone memoire partagee */
int j, no ; int fils;
if ( argc != 3)
erreur("usage : crible cle n \n") ;
n = atoi (argv[2]) ;

int i , n ; int fils; int *t ; /* adresse du tableau */


int shmid ; int mult ; char str_mult [10] ; char c;
if ( argc != 4)
erreur("usage : multiple cle n mult\n") ;
n = atoi(argv[2]) ; mult = atoi(argv[3]) ;
if((cle = ftok (argv[1] , 0 )) == -1 || n < 1)
erreur("Mauvaises parametres");
if((shmid = shmget(cle, n*sizeof(int) , 0 )) == -1 )
erreur("Le tableau en mem . partagee n'existe pas\n") ;
if(( t= (int*)shmat(shmid, NULL, 0)) == (int*)-1)
erreur("Erreur attachement au tableau en mem partagee\n") ;

if((cle = ftok (argv[1] , 0 )) == -1 || n < 1)


erreur("Mauvaises parametres");
if((shmid = shmget(cle, n*sizeof(int) , 0 )) == -1 )
erreur("Le tableau en mem. partagee n'existe pas\n") ;

if(mult <= n/2) {


printf( "Fils %d cherche multiples de %d\n", getpid(), mult );

sleep(1);
switch ( (fils = fork()) ) {
case -1 :
perror("fork echoue") ; exit(0) ;
case 0 : /*processus fils */
for(i=mult ; i<n ; i++)
if(t[i]) {
sprintf(str_mult, "%d", t[i]) ;

if(( t= (int*) shmat(shmid, NULL, 0)) == (int*)-1)


erreur("Erreur attachement au tableau en mem partagee\n") ;
signal(SIGCHLD , fin) ; // signal recu quand un fils se termine
switch ( fork() ) {
case -1 :
perror("fork echoue") ;
fin(0) ;

execlp("multiple_v1","multiple_v1",argv[1], argv[2],str_mult,NULL);

erreur("Erreur exec multiples") ;


}
exit(0) ;
default : /* processus pere */
while( wait(0) != fils);
for(i=2*mult-1 ; i<n ; i=i+mult)
t[i] = 0 ;
} /* fini switch */
} /* fini if (mult<n/2) */
exit(0);

case 0 : /*processus fils */


printf("1er fils Pid %d lance recherche multiples\n", getpid());

sleep(1) ;
execlp("multiple_v1","multiple_v1",argv[1], argv[2], "2", NULL) ;

erreur("Erreur fork main") ;


default : /* processus pere */
pause() ;
} /* fini switch */
}

13

14