Écrire un programme mysignal
qui:
pid
,sigaction(2)
, pour le signal SIGUSR1
qui affiche le numéro du signal reçu.Lancer le programme et tester l’effet des différents signaux avec la commande shell kill(1)
sur l’exécution du programme.
On peut éventuellement mettre une boucle while autour de l’appel à sigsuspend
pour ne pas relancer systématiquement le programme.
Essayer notamment l’enchaînement SIGSTOP
, SIGCONT
, SIGUSR1
, ou le signal SIGKILL
. Que se passe-t-il ?
Le but de cet exercice est de reprendre l’exercice précédent pour
faire communiquer 2 processus au travers d’une zone mémoire partagée
par mmap
: sig_receveur.c
et sig_expediteur.c
sig_receveur.c
qui fait:
mmap(2)
de ce fichiersigsupsend
sur le signal SIGUSR1
SIGUSR1
à l’aide de la commande kill(1)
sig_expediteur.c
qui fait:
mmap(2)
de ce fichier,SIGUSR1
.mmap
anonymeÉcrire un programme map_anonymous.c
qui:
p = mmap(NULL, sizeof(int), PROT, MAP_PRIVATE | MAP_ANONYMOUS, -1, 0);
%p
de fprintf(3)
.*p
avec le formatage %d
.%d
avant de terminer.On passera la variable de pré-processeur PROT en argument du compilateur de la façon suivante:
make map_anonymous CFLAGS+='-DPROT=PROT_NONE' && mv map_anonymous map_none
make map_anonymous CFLAGS+='-DPROT=PROT_READ' && mv map_anonymous map_read
make map_anonymous CFLAGS+='-DPROT=PROT_WRITE' && mv map_anonymous map_write
make map_anonymous CFLAGS+='-DPROT=PROT_EXEC' && mv map_anonymous map_exec
make map_anonymous CFLAGS+='-DPROT="PROT_EXEC | PROT_WRITE"' && mv map_anonymous map_ew
Exécuter ces programmes et expliquer ce qu’il se passe en vous aidant de la page de manuel de mmap(2)
. Expliquer ce qui se passe.
On souhaite partager entre plusieurs processus le code d’une
fonction, sans que cette fonction fasse partie de l’exécutable des
processus. On va pour cela reproduire le fonctionnement d’une
bibliothèque partagée, chargée dynamiquement (man dlopen, dlsym
). Pour cela, on écrira d’abord un programme qui copie une
fonction dans une zone mémoire partagée, puis un autre programme qui
partage cette zone mémoire et appelle la fonction:
load_add.c
:
add(int, int)
qui renvoie la somme de ses deux arguments.write(2)
un fichier libadd.a
de 2048 octets (s’il n’existe pas).mmap(2)
. Pour cela, on utilisera les flags PROT_WRITE|PROT_EXEC
et MAP_SHARED
.memcpy(3)
les 2048 premiers octets correspondant à la fonction add
dans la zone de mémoire partagée créée à l’aide de mmap(2)
.use_add.c
:
libadd.a
. On utilisera les flags PROT_EXEC
et MAP_SHARED
pour pouvoir exécuter le code de cette zone mémoire.f
de type int (*)(int, int)
avec l’adresse de cette zone mémoire.f(42,12)
et afficher le résultat.use
dans différents shells ?L’allocation d’un segment de mémoire partagée avec shmat(2)
nécessite d’abord d’obtenir un identifiant de ce segment avec
shmget(2)
. Cet identifiant peut être obtenu à l’aide d’une clé créée avec ftok(3)
.
shmget(2)
et ftok(3)
.
ftok(2)
, on utilisera le nom d’un fichier système (par ex. /etc/bashrc
).shmget(2)
, on utilisera une taille de 1024 octets et pour le flag, la valeur IPC_CREAT | 0644
.shmat(2)
, comme un tableau d’entiers.shmdt(2)
babaorum
), et recommencez l’expérience.PID
des autres processus partageant ce segment. On utilisera le segment mémoire pour stocker le nombre de PIDs suivi du tableau des
PIDs partageant la mémoire.fork(2)
dans une boucle for de 1 à 4 pour créer 16 processus partageant un segment commun. Le processus initial affichera avant de quitter la liste des processus partageant le segment de mémoire avec lui. Faire plusieurs exécutions (éventuellement passer à 32 processus créés). Qu’observez-vous ?