changement du fichier tp scr

This commit is contained in:
2025-10-23 14:29:21 +02:00
parent fb76e22594
commit df89b08f5d
27 changed files with 0 additions and 0 deletions

View File

@@ -0,0 +1,46 @@
#include <stdio.h> // pour printf, fprintf, fopen, fread, fwrite, fclose
#include <stdlib.h> // pour exit()
int main(int argc, char *argv[]) {
FILE *source, *dest; // pointeurs de fichiers
char c; // variable pour stocker un octet lu
// Vérifier que l'utilisateur a bien fourni deux arguments (source et destination)
if (argc != 3) {
fprintf(stderr, "Usage: %s <fichier_source> <fichier_dest>\n", argv[0]);
exit(1); // quitte le programme avec code d'erreur
}
// Ouvrir le fichier source en mode lecture binaire ("rb")
source = fopen(argv[1], "rb");
if (source == NULL) { // si l'ouverture échoue
perror("Erreur ouverture source");
exit(1);
}
// Ouvrir ou créer le fichier destination en mode écriture binaire ("wb")
dest = fopen(argv[2], "wb");
if (dest == NULL) { // si l'ouverture échoue
perror("Erreur ouverture destination");
fclose(source); // on ferme le fichier source déjà ouvert
exit(1);
}
// Lire un octet depuis le fichier source puis l'écrire dans le fichier destination
while (fread(&c, 1, 1, source) == 1) {
if (fwrite(&c, 1, 1, dest) != 1) {
perror("Erreur écriture");
fclose(source);
fclose(dest);
exit(1);
}
}
// Fermer les deux fichiers
fclose(source);
fclose(dest);
// Indiquer que la copie s'est terminée correctement
printf("Copie terminée (méthode stdio).\n");
return 0; // programme terminé sans erreur
}

View File

@@ -0,0 +1,49 @@
#include <stdio.h> // pour perror() et printf() : fonctions daffichage
#include <stdlib.h> // pour exit() : permet de quitter le programme en cas derreur
#include <fcntl.h> // pour open() : ouverture de fichiers
#include <unistd.h> // pour read(), write(), close() : appels systèmes bas niveau
int main() {
int source, dest; // "descripteurs de fichiers" : nombres entiers utilisés par le système
char c; // variable qui va contenir un caractère (1 octet) lu depuis le fichier
// Ouvrir le fichier source en lecture seule (O_RDONLY)
source = open("source.txt", O_RDONLY);
if (source < 0) { // si la valeur < 0, cest que louverture a échoué
perror("Erreur ouverture source"); // affiche lerreur système
exit(1); // quitte le programme avec un code derreur
}
// Créer (si nexiste pas) ou ouvrir le fichier destination en écriture
// O_WRONLY = écriture seule
// O_CREAT = créer le fichier si nexiste pas
// O_TRUNC = vider le fichier sil existe déjà
// 0644 = permissions du fichier (rw-r--r--)
dest = open("dest.txt", O_WRONLY | O_CREAT | O_TRUNC, 0644);
if (dest < 0) { // si louverture échoue
perror("Erreur ouverture destination");
close(source); // on ferme quand même le fichier source ouvert
exit(1);
}
// Lire et écrire le fichier octet par octet
// read(source, &c, 1) lit 1 octet du fichier source et le stocke dans c
// la boucle continue tant que read() lit bien 1 octet
while (read(source, &c, 1) == 1) {
// écrire cet octet dans le fichier destination
if (write(dest, &c, 1) != 1) { // si write() échoue
perror("Erreur écriture");
close(source);
close(dest);
exit(1);
}
}
// Fermer les deux fichiers
close(source);
close(dest);
// Indiquer à lutilisateur que tout sest bien passé
printf("Copie terminée (méthode appels système).\n");
return 0; // programme terminé correctement
}

View File

BIN
TP_SCR3.1/TP_Memoire/buf Executable file

Binary file not shown.

View File

@@ -0,0 +1,9 @@
#include "helpers.h"
static char buffer[16 MB] = {0};
int main(int argc, char **argv)
{
randomize(buffer, 16 MB);
return interlude();
}

View File

@@ -0,0 +1,8 @@
#include "helpers.h"
int main(int argc, char **argv)
{
dirty(16 MB);
clean(32 MB);
return interlude();
}

BIN
TP_SCR3.1/TP_Memoire/heap.o Normal file

Binary file not shown.

View File

@@ -0,0 +1,36 @@
#include <unistd.h>
#include <stdio.h>
#include <string.h>
#include <assert.h>
#include "helpers.h"
#include <stdlib.h>
void randomize(char *buf, size_t n)
{
assert(buf);
memset(buf, rand() & 0xff, n);
}
void clean(size_t b)
{
for (; b > 0; b -= 1 KB)
calloc(1 KB, sizeof(char));
}
void dirty(size_t b)
{
for (; b > 0; b -= 1 KB)
randomize(calloc(1 KB, sizeof(char)), 1 KB);
}
int interlude(void)
{
pid_t pid = getpid();
printf("pid %i\n", (int)pid);
printf("------------------------------------------\n"
"go check /proc/%i/smaps; I'll wait...\n"
"press <Enter> when you're done\n", pid);
fgetc(stdin);
return 0;
}

View File

@@ -0,0 +1,13 @@
#ifndef _HELPERS_H
#define _HELPERS_H
#include <stdlib.h>
#define KB * 1024
#define MB * 1024 * 1024
void randomize(char *buf, size_t n);
void clean(size_t n);
void dirty(size_t n);
int interlude(void);
#endif

Binary file not shown.

View File

@@ -0,0 +1,12 @@
#include "helpers.h"
int main(int argc, char **argv)
{
char *under = malloc(96 KB);
randomize(under, 96 KB);
char *over = malloc(256 KB);
randomize(over, 256 KB);
return interlude();
}

View File

@@ -0,0 +1,27 @@
/* adresses virtuelles d'un processus */
#include<stdio.h>
#include<sys/types.h>
#include <sys/time.h>
#include<unistd.h>
#include<stdlib.h>
int t[1000] = {[0 ... 999] = 2};
int main(int argc, char * argv[])
{
int i=3;
static int j = 3;
char * m = (char*)malloc(1);
printf("je suis le pid %d\n\n",getpid());
/* ------- Affichage des adresses --------*/
printf("main\t\t=\t%p\n",main);
printf("gettimeofday\t=\t%p\n",gettimeofday);
printf("&argc\t\t=\t%p\n",&argc);
printf("&i\t\t=\t%p\n",&i);
printf("&j\t\t=\t%p\n",&j);
printf("t\t\t=\t%p\n",t);
printf("m\t\t=\t%p\n",m);
getchar();
}

View File

@@ -0,0 +1,38 @@
#include "helpers.h"
#include <sys/mman.h>
#include <assert.h>
#include <fcntl.h>
int main(int argc, char **argv)
{
/* inert map (never modified) */
char *inert = mmap(NULL, 16 KB,
PROT_READ|PROT_WRITE,
MAP_ANONYMOUS|MAP_PRIVATE,
-1, 0);
/* anonymous, private mmap */
char *anon_priv = mmap(NULL, 32 KB,
PROT_READ|PROT_WRITE,
MAP_ANONYMOUS|MAP_PRIVATE,
-1, 0);
randomize(anon_priv, 32 KB);
/* anonymous, shared map */
char *anon_shared = mmap(NULL, 64 KB,
PROT_READ|PROT_WRITE,
MAP_ANONYMOUS|MAP_SHARED,
-1, 0);
randomize(anon_shared, 64 KB);
/* private, file-backed map */
int fd = open("data/256k", O_RDWR);
assert(fd >= 0);
char *file = mmap(NULL, 256 KB,
PROT_READ|PROT_WRITE,
MAP_PRIVATE,
fd, 0);
randomize(file, 128 KB);
return interlude();
}

View File

@@ -0,0 +1,6 @@
#include "helpers.h"
int main(int argc, char **argv)
{
return interlude();
}

View File

@@ -0,0 +1,8 @@
#include "helpers.h"
int main (int argc, char **argv)
{
char buf[28 KB] = {0};
randomize(buf, 28 KB);
return interlude();
}

View File

@@ -0,0 +1,180 @@
TP1 MEMOIRE - YOLOU
1. Ce que je dois comprendre sur le code le processus possède une mémoire qui contient des adresses virtuelles
vdsco ce sont des appels systeme y'en a que 4 get of day c'est un appel systeme, le prgramme considere que c'est un appel systeme mais ca n'utilise pas l'organisation du noyaux (sauvegarde, rechargement etc...)
[yolou@salle223-10 TP_Memoire]$ ./a.out
je suis le pid 23540
main = 0x559308d20179
gettimeofday = 0x7f08d7032870
&argc = 0x7ffd6bca825c
&i = 0x7ffd6bca826c
&j = 0x559308d24000
t = 0x559308d23060
m = 0x559320a82310
^Z
[1]+ Stopped ./a.out
[yolou@salle223-10 TP_Memoire]$ cat /proc/23540/maps
adresse début adresse fin perms offset devices inode chemin
559308d1f000-559308d20000 r--p 00000000 00:3e (périphèrique) 70729069 /export/home/info-but24/yolou/BUT2/TP_SCR/TP_Memoire/a.out
559308d20000-559308d21000 r-xp 00001000 00:3e 70729069 /export/home/info-but24/yolou/BUT2/TP_SCR/TP_Memoire/a.out
559308d21000-559308d22000 r--p 00002000 00:3e 70729069 /export/home/info-but24/yolou/BUT2/TP_SCR/TP_Memoire/a.out
559308d22000-559308d23000 r--p 00002000 00:3e 70729069 /export/home/info-but24/yolou/BUT2/TP_SCR/TP_Memoire/a.out
559308d23000-559308d25000 rw-p 00003000 00:3e 70729069 /export/home/info-but24/yolou/BUT2/TP_SCR/TP_Memoire/a.out
559320a82000-559320aa3000 rw-p 00000000 00:00 0 [heap]
7f08d6c00000-7f08d6c24000 r--p 00000000 103:05 6028 /usr/lib/libc.so.6
7f08d6c24000-7f08d6d96000 r-xp 00024000 103:05 6028 /usr/lib/libc.so.6
7f08d6d96000-7f08d6e05000 r--p 00196000 103:05 6028 /usr/lib/libc.so.6
7f08d6e05000-7f08d6e09000 r--p 00204000 103:05 6028 /usr/lib/libc.so.6
7f08d6e09000-7f08d6e0b000 rw-p 00208000 103:05 6028 /usr/lib/libc.so.6
7f08d6e0b000-7f08d6e13000 rw-p 00000000 00:00 0
7f08d6ffb000-7f08d7000000 rw-p 00000000 00:00 0
7f08d702c000-7f08d7030000 r--p 00000000 00:00 0 [vvar]
7f08d7030000-7f08d7032000 r--p 00000000 00:00 0 [vvar_vclock]
7f08d7032000-7f08d7034000 r-xp 00000000 00:00 0 [vdso]
7f08d7034000-7f08d7035000 r--p 00000000 103:05 6019 /usr/lib/ld-linux-x86-64.so.2 (=> mappage dans le disque dur, quand on invoque le printf etc c'est ici qu'il vient ressourcer)
7f08d7035000-7f08d705f000 r-xp 00001000 103:05 6019 /usr/lib/ld-linux-x86-64.so.2
7f08d705f000-7f08d706d000 r--p 0002b000 103:05 6019 /usr/lib/ld-linux-x86-64.so.2
7f08d706d000-7f08d706f000 r--p 00039000 103:05 6019 /usr/lib/ld-linux-x86-64.so.2
7f08d706f000-7f08d7070000 rw-p 0003b000 103:05 6019 /usr/lib/ld-linux-x86-64.so.2
7f08d7070000-7f08d7071000 rw-p 00000000 00:00 0
7ffd6bc89000-7ffd6bcaa000 rw-p 00000000 00:00 0 [stack]
ffffffffff600000-ffffffffff601000 --xp 00000000 00:00 0 [vsyscall]
Bibliotheque dynamique dln windows /
Bibl. standard C libsc :
. La libc contient les fonctions comme printf, malloc, exit...
. PLusieurs segment comme :
. r-xp = code éxécutable de la bibliothèque
. r-p = données en lecture seule
. rw-p = données globales de la libc.
[vvar] :
. Virtual Variables : zone créée par le noyau pour partager certaines infos comme l'horloge entre le noyau et ton programme
. Lecture seule.
id-linux (linker dynamique) :
Le chargeur dynamique : c'est lui qui charge les biblio partagé comme libc en mémoire
Il est obligatoire pour éxécuter un programme avec des bibliothèques dynamiques
[stack] (pile) :
La pile du processus
Sert a stocker : variable locales, adresse de retour des fonctions, parametres.
Grandit quand tu appelles des fonctions imbriquées.
Adresse-debut/fin = adresses virtuelles
il y a les perms : r-xp = lecture + execution -> segment code
r-p = lecture seul -> constantes
rw-p = lecture/écriture -> variables globales initialisées
Virtual Dymanic Shared Object => Petite zone pour accelerer certains appels systeme (ex gettimeofday) = vsdo
Heap(tas) :
. zone utilisée pour les allocations dynamiques(malloc,callocfree)
. grandit ou rétrécit selon les besoins.
2)
Apres avoir fait la commande pmap -x <piud>, j'observe que il y'a plusieurs adresses :
Addresss -> l'adresse virtuelle oû commence ce segment mémoire
Kbytes -> taille totale du segments (réservée)
RSS (Resident Set Size) -> combien de mémoire de ce segment est réellement physqiuement en RAM (le reste peut etre sur disque ou pas encore utilisé) pour savoir si elle sont mappé physiquement
Dirty -> nombre de Kilo octet modifiés (non partagés, spécifiques à mon processus)
Mode -> permission du segment :
r, w, x, s ou p : partagé (shared) ou prié (private)
Mapping -> d'oû vient ce segment (exécutable a.out, biblliothèque, [stack], [heap], [anone] pour anonyme)
Typiquement avec le prgramme du premier exo :
113416: ./a.out
Address Kbytes RSS Dirty Mode Mapping
000055c06db68000 4 4 0 r---- a.out
000055c06db69000 4 4 0 r-x-- a.out
000055c06db6a000 4 4 0 r---- a.out
000055c06db6b000 4 4 4 r---- a.out
000055c06db6c000 8 8 8 rw--- a.out
000055c091c49000 132 4 4 rw--- [ anon ]
00007f0f90000000 144 144 0 r---- libc.so.6
00007f0f90024000 1480 1060 0 r-x-- libc.so.6
00007f0f90196000 444 128 0 r---- libc.so.6
00007f0f90205000 16 16 16 r---- libc.so.6
00007f0f90209000 8 8 8 rw--- libc.so.6
00007f0f9020b000 32 20 20 rw--- [ anon ]
00007f0f903f9000 20 12 12 rw--- [ anon ]
00007f0f9042b000 16 0 0 r---- [ anon ]
00007f0f9042f000 8 0 0 r---- [ anon ]
00007f0f90431000 8 8 0 r-x-- [ anon ]
00007f0f90433000 4 4 0 r---- ld-linux-x86-64.so.2
00007f0f90434000 168 168 0 r-x-- ld-linux-x86-64.so.2
00007f0f9045e000 56 56 0 r---- ld-linux-x86-64.so.2
00007f0f9046c000 8 8 8 r---- ld-linux-x86-64.so.2
00007f0f9046e000 4 4 4 rw--- ld-linux-x86-64.so.2
00007f0f9046f000 4 4 4 rw--- [ anon ]
00007ffc6a1a9000 132 12 12 rw--- [ stack ]
ffffffffff600000 4 0 0 --x-- [ anon ]
---------------- ------- ------- -------
total kB 2712 1680 100
1. a.out (mon prgm)
Aplusieurs lignes avec a.out :
r-x -> segment code exécutable
r-- -> données en lecture seule (constates)
rw- -> données globales modifiables
2. [anone] (anonyme)
Memoire réservée par le processus sans fichier associé
Ici ca peut etre des petit malloc
3. libc.so.6
La bibliothèque standard du C (printf,malloc, ...).
.r-x -> code éxécutable de la libc
. rw- -> données de la libc
4. Id-linux x86-64.so.2
Le chargeur dynamique qui charge les bibliothèque
Lui aussi a code (r-x) et données (rw-).
total kB : 2712
Le processus occupe environ 2.7 Mo au total.
Sur ces 2712 Ko, 1680 Ko sont effectivement en RAM (RSS).
Le reste peut etre reservé mais pas encore utilisé.
Généralement, le programme est découpé en segments mémoire : code, données, heap, pile, bibliothéques, mappings, anonymes.
La commande pmap -x permet de voir :
combien est réservé (Kbvtes) le processus,
cobmien est vraiment en RAM (RSS),
combien est spécifique au processus (Dirty)
et pour finir l'origine du segment (Mapping)
Ca illustre le cours le cours sur l'organisation mémoire d'un processus et la gestion par Linux via mémoire vituelle + MMU (MMU pour memory management unit), un composant informatique responsable de l'accès à la mémoire demandée par le processeur).
Pour le code buf :
Pour les segments "buf" (l'executable)
Plusierus petites lignes de 4kB avec buf :
r-x -> code éxécutable

BIN
TP_SCR3.1/TP_SIGNAUX/parexec Executable file

Binary file not shown.

View File

@@ -0,0 +1,36 @@
#include <assert.h>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/wait.h>
int main(int argc, char* argv[])
{
// TODO
assert(argc >= 2);
// char prog = argv[1];
for(int i=2; i<argc; i++){
pid_t pid = fork();
if(pid == 0){
execlp(argv[1], argv[1], argv[i], NULL);
}
}
for(int i=2; i<argc; i++){
wait(NULL);
}
}

View File

@@ -0,0 +1,119 @@
/*
* parexec_lim.c
* Q3 : Lancer au plus N instances en parallèle : ./parexec_lim prog N arg1 [arg2 ...]
* Q4 : Si une instance se termine à cause d'un SIGNAL -> tuer toutes les autres et arrêter.
*/
#include <stdio.h> // fprintf, perror
#include <stdlib.h> // atoi, calloc, free, EXIT_*
#include <unistd.h> // fork, execlp, usleep
#include <sys/wait.h> // wait, WIFSIGNALED, WTERMSIG
#include <signal.h> // kill
#include <errno.h> // errno
int main(int argc, char *argv[]) {
// Vérifie la syntaxe minimale : prog + N + au moins 1 argument pour prog
if (argc < 4) {
fprintf(stderr, "Usage: %s prog N arg1 [arg2 ...]\n", argv[0]);
return EXIT_FAILURE;
}
char *prog = argv[1]; // le programme à lancer (ex: "./rebours")
int N = atoi(argv[2]); // nombre maximum d'enfants en parallèle
if (N <= 0) { // N doit être strictement positif
fprintf(stderr, "N doit être > 0\n");
return EXIT_FAILURE;
}
int next = 3; // index du prochain argument à donner à prog (argv[3] au début)
int running = 0; // nombre d'enfants actuellement en cours d'exécution
int stop = 0; // =1 si on a détecté une fin anormale -> on arrête de relancer
// Tableau des PIDs des enfants "actifs" (taille N). 0 signifie "case libre".
pid_t *slots = calloc((size_t)N, sizeof(pid_t));
if (!slots) { perror("calloc"); return EXIT_FAILURE; }
// ===== 1) Lancer tout de suite jusqu'à N enfants (ou jusqu'à épuisement des args) =====
while (!stop && running < N && next < argc) {
pid_t pid = fork(); // crée un nouveau processus
if (pid == 0) { // dans l'enfant
execlp(prog, prog, argv[next], NULL); // remplace l'enfant par "prog argi"
_exit(127); // si exec échoue, sortir avec code 127
}
if (pid < 0) { // fork a échoué dans le parent
perror("fork");
stop = 1; // on arrête les lancements
break;
}
// Ici on est dans le parent et fork a réussi : on mémorise le PID dans une case libre 2 5 4 3
for (int i = 0; i < N; ++i) {
if (slots[i] == 0) { // 0 = case libre
slots[i] = pid; // on range ce PID
break;
}
}
running++; // on a un enfant de plus
next++; // prochain argument à utiliser
}
// ===== 2) Boucle principale : attendre les fins, réagir, et (éventuellement) relancer =====
while (running > 0) { // tant qu'il reste des enfants actifs
int status = 0;
pid_t pid = wait(&status); // attendre qu'UN enfant se termine
if (pid < 0) { // erreur (souvent EINTR). On simplifie : on réessaie.
if (errno == EINTR){
continue;
}
perror("wait");
break;
}
// Retirer ce PID du tableau des actifs (libérer sa case)
for (int i = 0; i < N; ++i) {
if (slots[i] == pid) { // on a trouvé la case de cet enfant
slots[i] = 0; // on marque la case vide
break;
}
}
running--; // un enfant en moins
// ===== Q4 : si l'enfant s'est terminé à cause d'un SIGNAL =====
if (WIFSIGNALED(status)) {
stop = 1; // ne plus lancer de nouveaux enfants
// D'abord demander gentiment aux autres de s'arrêter
for (int i = 0; i < N; ++i) {
if (slots[i] > 0) kill(slots[i], SIGTERM);
}
usleep(100000); // petite pause (100 ms)
// Puis forcer l'arrêt si certains sont encore vivants
for (int i = 0; i < N; ++i) {
if (slots[i] > 0) kill(slots[i], SIGKILL);
}
// on n'ajoute PAS de relance ici (stop=1)
}
// ===== Relancer si : pas d'arrêt global ET il reste des arguments à lancer =====
if (!stop && next < argc) {
pid_t npid = fork(); // crée un nouvel enfant
if (npid == 0) { // dans le nouvel enfant
execlp(prog, prog, argv[next], NULL); // lance "prog arg"
_exit(127); // si exec échoue
}
if (npid < 0) { // fork a échoué
perror("fork");
stop = 1; // arrêter les relances
} else {
// ranger ce nouveau PID dans une case libre
for (int i = 0; i < N; ++i) {
if (slots[i] == 0) { slots[i] = npid; break; }
}
running++; // un enfant de plus en cours
next++; // passera à l'argument suivant lors de la prochaine relance
}
}
}
free(slots); // libérer la mémoire
if (stop) return 1; // échec
return 0; // succès
}

BIN
TP_SCR3.1/TP_SIGNAUX/rebours Executable file

Binary file not shown.

View File

@@ -0,0 +1,19 @@
#include <assert.h>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
int main(int argc, char* argv[])
{
assert(argc == 2);
int value = strtol(argv[1], NULL, 0);
pid_t p = getpid();
printf("%d: debut\n",p);
for(int i = value; i>0; i--){
printf("%d: %d\n",p,i);
sleep(1);
}
printf("%d: fin\n",p);
return EXIT_SUCCESS;
}

BIN
TP_SCR3.1/TP_Threads/a.out Executable file

Binary file not shown.

View File

@@ -0,0 +1,49 @@
#include <stdio.h>
#include <stdlib.h>
#include <pthread.h>
#include <assert.h>
#define NUM_THREADS 16
void *thread(void *thread_id) {
long id = ((long ) thread_id);
printf("Hello from thread %ld\n", id);
return (void*)(2*id);
}
int main() {
pthread_t threads[NUM_THREADS];
int t[NUM_THREADS];
long res;
for (long i = 0; i < NUM_THREADS; i++){
// t[i] = i;
assert( pthread_create(&threads[i], NULL, thread, (void*)i) == 0);
}
for (int i = 0; i < NUM_THREADS; i++){
assert( pthread_join(threads[i],(void *)&res) == 0);
printf("%ld\n",res);
}
return EXIT_SUCCESS;
}
// 1.L'execution est-elle correcte ?
// Non la version est fause
/*On voit parfois des IDS faux/repetés selon les exécutions.
2. Si ce n'est pas le cas, expliquez pourquoi
Probleme :
(Parce qu'on passe l'adresse d'une variable partagée (&i) qui change pendant la creation des threads.
Les threads lisent la meme adresse, pas uenc opie de la valeur -> condition de course + duree de vie/visibilité non garanties)
&i est l'adresse de la meme variable i de la bouche (une seule variable, qui change de valeur).
Les threads démarrent en parrallèle et lisent tous la meme adresse.h
Comme i continue de s'incrementer, le contenu vu par les threads depends du timing -> plusieurs threads peuvent lire la meme valeur, ou tous lire la valeur finale(16);
Resultat : sorties incorrects / pas vraiment deterministes(certains IDs manquent, d'autres répétes).*/
// Exercie 2 :

View File

@@ -0,0 +1,29 @@
#include <stdio.h>
#include <stdlib.h>
#include <pthread.h>
#include <assert.h>
int main(int argc, char *argv[]){
if(argc != 3) {
fprintf(stderr, "Usage :%s <max> <n>\n",argv[0]);
return 1;
}
long N = strtol(argv[1], NULL,0);
long M = strtol(argv[2], NULL,0);
}

BIN
TP_SCR3.1/TP_Tubes/a.out Executable file

Binary file not shown.

72
TP_SCR3.1/TP_Tubes/ex1.c Normal file
View File

@@ -0,0 +1,72 @@
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/types.h>
int main(void) {
int p[2]; // tube : p[0] lecture, p[1] écriture
pid_t pf1, pf1f1, pf2;
pipe(p);
// --- créer Pf1 ---
pf1 = fork();
if (pf1 == 0) {
// --- créer Pf1f1 ---
pf1f1 = fork();
if (pf1f1 == 0) {
// Pf1f1 : lecteur
close(p[1]); // ne garde que la lecture
while (1) {
pid_t v;
read(p[0], &v, sizeof(v));
int valeur = read(p[0], &v, sizeof(v));
printf(" %d received %d\n", (int)getpid(), (int)v);
fflush(stdout);
sleep(1);
}
}
close(p[0]);
close(p[1]);
while (1){
pause();
}
}
// --- créer Pf2 ---
pf2 = fork();
if (pf2 == 0) {
//Pf2 : écrivain
close(p[0]); // ne garde que lécriture
pid_t cmoi = getpid();
while (1) {
printf("%d sent %d\n", (int)cmoi, (int)cmoi);
fflush(stdout);
write(p[1], &cmoi, sizeof(cmoi));
sleep(3);
}
}
//P COMME PAPA
close(p[0]);
close(p[1]);
while (1){
pause();
}
printf(valeur);
}
// Question 3 : (Envoyez le signal SIGSTOP à Pf2, puis le signal SIGCONT à Pf2)
// Pour le premiere comportement quand je stop le processus pf2 avec un kill -STOP 211912 alors mon programme est comme en pause c'est normal car l'action du prcessus de pf1f1 dependait du tube qui relie donc comme il a rien a recevoir il attend.
// Puis quand j'utilise SIGCONT le programme se debloque car le pf2 n'est plus gélé donc le pf1f1 peut lire les informations qu'on lui donne.
//(Envoyez le signal SIGSTOP à Pf1f1, puis le signal SIGCONT à Pf1f1.)
//Lors du moment ou j'ai envoyer ce signal le processus pf2 continue d'envoyé ses information au processus pf1f1 sauf que lui comme il est gelé ne reagit pas à sa "requete".
// Puis ainsi il rattrape tous ces requetes qui n'a pas pu repondre et du coup comme il est plus rapide que pf2 a la relance il a recup tous les pid possible comme dans le tube il etait rempli de ça donc il a lu les pid qui était la dans le tube.

45
TP_SCR3.1/TP_Tubes/ex11.c Normal file
View File

@@ -0,0 +1,45 @@
#include <fcntl.h>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <assert.h>
#include <sys/wait.h>
int main(int argc, char *argv[]){
if(argc != 3) {
fprintf(stderr, "Usage :%s <max> <n>\n",argv[0]);
return 1;
}
int maxv = atoll(argv[1]);
int n = atoi(argv[2]);
int p[2];
pipe(p);
for(int k=0; k<k*n; k++){
}
}