Consignes Examen 2021
  • Documents non autorisés : Email et messagerie

  • Documents autorisés : Sujets de TP et notes de cours

  • Durée de l’évaluation : 2 Heures

Merci de réinitialiser les machines virtuelles avant le début du TP
Comptes Rendus

Merci d’envoyer les comptes rendus de TP AVANT DE QUITTER LA SALLE à l’adresse suivante: kevin.toublanc@univ-tours.fr

MERCI DE RESPECTER LES CONTRAINTES CI-DESSOUS:

  • Objet du mail: [G1][ETUDIANT1][ETUDIANT2] TP SE 2021

  • Dans un ZIP :

    • Un fichier .c pour chaque exercice : exercice-1.c, exercice-2.c, …​

    • Un fichier .txt pour chaque question posée : question-1.txt, question-2.txt, …​

    • Ne m’envoyez pas les fichiers compilés (je recompilerai votre code)

Questions sur les travaux pratiques

Question 1

1
2
3
4
int main(void) {
    close(2);
    perror("Something went terribly wrong...");
}

Quel est l’effet de ce code ?

Question 2

Étant donné un programme qui :

  • Créé un processus fils (à l’aide d’un fork) pour effectuer une tâche très longue

  • Effectue un court traitement

  • Se termine avec une erreur de segmentation

Quel est l’état du processus fils ?

Question 3

La fonction kill(pid, signal_id) permet d’envoyer au processus pid le signal identifié par signal_id
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
void sigsegv_handler(int sig) {
    signal(SIGSEGV, SIG_DFL);
}

int main(void) {
    signal(SIGINT, SIG_IGN);
    signal(SIGSEGV, sigsegv_handler);

    kill(getpid(), SIGINT);
    kill(getpid(), SIGSEGV);
    kill(getpid(), SIGSEGV);
    return 0;
}
  • Quel est l’effet des lignes 6 et 7 ?

  • Quel est l’effet des lignes 9, 10 et 11 ?

  • Comment le programme se termine ?

Exercice 1

Écrivez un programme qui se duplique (via un fork).

Le processus fils exécute les instructions suivantes :

  • Affiche "Hello World From Child" sur la sortie standard

  • Se termine en retournant la valeur 42

Le processus père exécute les instructions suivantes :

  • Se duplique (fork)

  • Attend la fin du processus fils

  • Récupère la valeur retournée par le processus fils.

  • Se termine en retournant la valeur retournée par le processus fils multiplié par 10

Exercice 2

Créez un fichier output.txt

Écrivez un programme qui se duplique (via un fork).

Le processus fils exécute les instructions suivantes :

  • Ouvre un fichier output.txt (attention aux permissions)

  • Ferme sa sortie standard

  • Remplace sa sortie standard par le fichier output.txt

  • Écrit sur sa sortie standard (via les fonctions printf ou puts) "This message should be in the output.txt file"

Le processus père exécute les instructions suivantes :

  • Se duplique (fork)

  • Attend la fin du processus fils

  • Se termine en retournant 0

Exercice 3

Écrivez un programme répondant aux contraintes ci-dessous.

Le programme principal exécute les instructions suivantes :

  • Créé deux threads

  • Attend et récupère la valeur retournée par les deux threads

  • Se termine en retournant les valeurs récupérées additionnées

Le premier thread exécute les instructions suivantes :

  • Retourne la valeur 19

Le second thread exécute les instructions suivantes :

  • Retourne la valeur 56

Exercice 4

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
#include <pthread.h>
#include <stdlib.h>
#include <stdio.h>
#include <unistd.h>

long final_value = 0;

const int long_process(int i) {
    sleep(i);
    const int value = rand() % (1000 * i + 1); // Random value for 1 to i*1000
    printf("Processed value : %d\n", value);
    return value;
}

int main(int argc, char *argv[], char *arge[]) {
    srand(time(NULL)); // Initialize Random

    final_value += long_process(1);
    final_value += long_process(2);
    final_value += long_process(3);
    final_value += long_process(4);

    final_value = first_value + second_value + third_value + fourth_value;
    printf("Final processed value : %ld\n", final_value);

    return EXIT_SUCCESS;
}

Modifiez le programme ci-dessus pour que:

  • chaque calcul soit réalisé dans un thread différent mais utilisant la même fonction de traitement ;

  • le programme principal attende la fin de l’exécution de tous les threads avant de se terminer ;

  • les threads devront être créés en passant en argument le temps d’attente (argument de la fonction long_process()) ;

  • le calcul de la valeur finale (final_value) doit être réalisé par les threads;

  • la modification de la valeur finale (final_value) doit être protégée par le mécanisme de synchronisation le plus approprié.

N’oubliez pas de compiler avec l’option adéquate pour permettre l’accès aux fonctions de la librairie -lpthread

Exercice 5

Écrivez un programme répondant aux contraintes ci-dessous.

Le processus fils exécute les instructions suivantes :

  • Ferme son entrée standard

  • Remplace son entrée standard par la partie de lecture du tube (via dup)

  • Lit les messages depuis l’entrée standard et les affiche sur la sortie standard tant que le message "End\n" n’est pas reçu.

Le processus père exécute les instructions suivantes :

  • Créé un tube (pipe)

  • Se duplique (fork)

  • Écrit trois messages dans le tube : "Hello!\n", "How are you?\n", "End\n"

  • Attend la fin du processus fils

  • Se termine en retournant 0

Tips

Lecture depuis l’entrée standard

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
#include <stdio.h>
#include <string.h>

/**
* Lit l'entrée standard tant que '\n' n'est pas lu et retourne un pointeur vers une chaine de caractères.
* @warning L'appel de cette fonction est bloquant car elle utilise la fonction getchar()
* @return Une chaine de caractères initialisée
*/
const char *const read_from_stdin() {
    char buffer[255]= {};
    int car;
    int i = 0;
    while ((car = getchar()) != '\n' && i < 253) {
            buffer[i] = (char) car;
            i++;
    }
    buffer[i] = '\n';
    buffer[i+1] = '\0';
    return strdup(buffer);
}

Comparaison de chaine de caractères

1
2
3
4
5
#include <string.h>
void func(void) {
    strcmp("this", "that"); // returns something different from 0
    strcmp("this", "this"); // returns 0
}