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
printfouputs)"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
}