2023 PC Informatique
2023 PC Informatique
IP
B-
BI
EIS
IP
B-
BI
EIS
IP
B-
BI
EIS
IP
B-
BI
EIS
IP
B-
BI
EIS
IP
B-
BI
EIS
IP
B-
BI
EIS
IP
B-
BI
EIS
IP
B-
BI
EIS
IP
B-
BI
EIS
IP
B-
BI
EIS
IP
B-
BI
EIS
IP
B-
BI
EIS
IP
B-
BI
EIS
IP
B-
BI
EIS
IP
B-
BI
EIS
IP
B-
BI
EIS
IP
B-
BI
EIS
IP
B-
BI
EIS
IP
B-
BI
EIS
IP
B-
BI
EIS
IP
B-
BI
CONSIGNES GÉNÉRALES
Un processus est défini comme étant un programme chargé en mémoire centrale en vue d’être
exécuté par le processeur. Un processus est donc né lors du chargement d’un programme et se
IS
termine à la fin de l’exécution de ce programme. Un processus peut être à l’un des états suivants :
• Prêt : s’il dispose de toutes les ressources nécessaires à son exécution à l’exception du
processeur.
• Elu : s’il est en cours d’exécution par le processeur.
• Bloqué : s’il est en attente d’un événement ou bien d’une ressource pour pouvoir continuer.
Un ordonnanceur est un processus important du système d’exploitation qui gère l’allocation
du temps processeur. Plusieurs processus peuvent être à l’état "Prêt", dans ce cas l’ordonnanceur
se charge de choisir parmi eux celui qui devra être traité en premier lieu selon une stratégie
d’ordonnancement. Un ordonnanceur fait face à deux problèmes principaux :
— Comment élire un processus à exécuter parmi les processus prêts ?
— Durant combien de temps le processeur est alloué au processus élu ?
Attributs
• nomP, chaîne de caractères représentant le nom du processus (supposé unique).
• taP, entier représentant le temps d’arrivée du processus.
IP
Méthodes à implémenter
Q1. __init__(...) : initialise un processus à partir des paramètres nomP, taP, deP et etatP re-
présentant respectivement le nom du processus, son temps d’arrivée, sa durée d’exécution et
son état.
Exemple 1: L’objet processus P de nom "P", ayant un temps d’arrivée 1, une durée nécessaire
d’exécution 8 et l’état "Elu" est instancié comme suit :
Solution:
>>> str(P)
"Nom : P - Temps d’Arrivée : 1 - Durée d’Exécution : 8 - Etat : Elu"
BI
Solution:
B-
def __str__(self):
return "Nom:{} -Temps Arrivee:{} - Duree d'Exécution: {}-Etat:
,→ {}".format(self.nomP,self.taP,self.deP,self.etatP)
IP
ou bien
E
def __str__(self):
IS
ou bien
def __str__(self):
return "Nom : " + \
self.nomP + " - Temps d'arrivée : " + str(self.taP) + \
"- Durée d'exécution : " + str(self.deP) + \
"-Etat: " + self.etatP
Q3. __eq__(...) : retourne un booléen indiquant si les deux processus self et other ont le
même nom.
ou bien
def __eq__(self,other):
if self.nomP==other.nomP:
return True
else:
return False
Q4. changerEtat(...) : change l’état courant du processus vers l’état ns passé en paramètre.
BI
Solution:
B-
def changerEtat(self, ns):
self.etatP = ns
IP
Méthodes à implémenter
Solution:
class FileProcessus:
def __init__(self):
self.data = []
Q6. __len__(...) : retourne le nombre de processus présents dans l’instance actuelle de FileProcessus.
def __len__(self):
return len(self.data)
Q7. __str__(...) : permet de représenter un objet de type FileProcessus par une chaîne
selon le format suivant :
"""
Liste de processus : [
Nom : nomP1 - Temps Arrivée : taP1 - Durée d'Exécution : deP1 - Etat : etatP1,
Nom : nomP2 - Temps Arrivée : taP2 - Durée d'Exécution : deP2 - Etat : etatP2,
...
]
"""
Solution:
BI
def __str__(self):
return "Liste de processus:[\n{} \n]".format(",\n".join('\t' +
B-
def __str__(self):
E
ch="Liste de Processus:[\n"
for p in self.data:
IS
ch+=p.__str__()+"\n"
return ch+"]"
Q8. __contains__(...) : reçoit un processus p en paramètre et vérifie s’il est présent dans la
file actuelle.
Solution:
def __contains___(self,p):
return p in self.data
def __contains__(self,p):
if p in self.data:
return True
return False
BI
B-
IP
E IS
Solution:
Q10. nomProcessusElu(self) : retourne le nom du premier processus ayant l’état "Elu" dans la
file actuelle, None si aucun processus ne dispose de l’état "Elu".
Solution:
def nomProcessusElu(self):
BI
for p in self.data:
if p.etatP == "Elu":
return p.nomP
B-
Solution:
E
def ajouterProcessus(self,p):
IS
Solution:
def retirerProcessus(self,nomP):
p = self[nomP]
assert p is not None, "Erreur processus n'est pas représenté !!!"
self.data.remove(p)
return p
Méthodes à implémenter
IP
Solution:
IS
class StratégieOrdonnacement:
def __init__(self, fp):
self.fp = fp
self.horloge = 0
self.stats = {}
def elire(self):
# pour cette classe le script de cette méthode
# n'est pas demandé
et
IP
tat Pi = tr Pi − deP Pi
E
— si le processus p n’est pas encore achevé, changer son état à "Prêt" et le remettre dans
fp.
Solution:
Q15. simuler(...) : prend en paramètre un entier positif duree (durée totale de la simulation)
B-
La simulation s’arrête quand l’horloge dépasse duree ou bien jusqu’à l’achèvement de l’exé-
cution des processus de la file fp.
E
Solution:
IS
Q16. criteres(...) : calcule et retourne un tuple contenant le temps de réponse moyen (TRM)
et le temps d’attente moyen (TAM) calculés à partir du dictionnaire stats en se basant sur
les formules suivantes :
Solution:
BI
def criteres(self):
strr = sum(t[0] for t in self.stats.values())
B-
sta = sum(t[1] for t in self.stats.values())
return (strr/ len(self.stats), sta / len(self.stats) ) if
,→ len(self.stats) != 0 else (float("nan"), float("nan"))
IP
ou bien
E
def criteres(self):
IS
return tuple(np.array(self.stats.values()).mean(axis = 0))
ou bien
def criteres(self):
assert len(self.stats)!=0,"STATS EST VIDE"
L1=[]
L2=[]
for t in self.stats.values():
L1.append(t[0])
L2.append(t[1])
TRM=sum(L1)/len(L1)
TAM=sum(L2)/len(L2)
return TRM,TAM
Q17. elire(...) : élit le processus ayant le temps d’arrivée minimal parmi les processus ayant
un temps d’arrivée inférieur ou égal à l’instant actuel de l’horloge.
Solution:
class FCFS(StratégieOrdonnacement):
def elire(self):
p = min(self.fp.data, key = lambda p : p.taP)
if p.taP <= self.horloge:
p.changerEtat("Elu")
ou bien
class FCFS(StratégieOrdonnancement):
BI
def elire(self):
L=[]
for p in self.fp.data:
B-
L.append((p.taP,p))
L.sort()
if L[0][0]<=self.horloge:
L[0][1].changerEtat("Elu")
IP
E
Méthodes à implémenter
Q18. elire(...) : élit le processus ayant la plus courte durée d’exécution avec un temps d’arrivée
inférieur ou égal au temps courant de l’horloge.
Solution:
class SJF(StratégieOrdonnacement):
def elire(self):
lst = [p for p in self.fp.data if p.taP <= self.horloge]
if len(lst) != 0:
p = min(lst, key = lambda p : p.deP)
p.changerEtat("Elu")
class SJF(StratégieOrdonnancement):
def elire(self):
L=[]
for p in self.fp.data:
if p.taP<=self.horloge:
L.append((p.deP,p))
if len(L)!=0:
L.sort()
L[0][1].changerEtat("Elu")
Méthodes à implémenter
B-
Solution:
IP
class RR(StratégieOrdonnacement):
E
def __init__(self, fp, q):
super().__init__(fp)
IS
self.q = q
Solution:
def executer(self):
super().executer(self.q)
Q21. elire(...) : élit le premier processus de la file ayant un temps d’arrivée inférieur ou égal
au temps courant de l’horloge.
Solution:
def elire(self):
for p in self.fp.data:
if p.taP <= self.horloge:
p.changerEtat("Elu")
break
BI
B-
A#0#3#Prêt
B#1#8#Prêt
C#2#6#Prêt
D#3#4#Bloqué
E#4#4#Prêt
F#6#5#Prêt
G#8#2#Prêt
H#9#1#Prêt
Solution:
def ProcessusTxt(ligne):
lst = ligne.split("#")
lst[1] = int(lst[1])
lst[2] = int(lst[2])
return Processus(*lst) #return Processus(lst[0], lst[1], lst[2], lst[-1])
Q23. Écrire une fonction nommée chargement qui prend en entrée nomF le nom d’un fichier texte
(comme indiqué sur la figure 1) et retourne une instance de la classe FileProcessus contenant
tous les processus du fichier.
Solution:
BI
def chargement(nomf):
fp = FileProcessus()
B-
f = open(nomf, "r")
for line in f:
p = ProcessusTxt(line.strip())
IP
fp.ajouterProcessus(p)
f.close()
return fp
E IS
Solution: ou bien
def chargement(nomf):
fp = FileProcessus()
f = open(nomf, "r")
L=f.readlines()
L=[i.strip() for i in L]
for ligne in L:
p = ProcessusTxt(ligne)
fp.ajouterProcessus(p)
f.close()
return fp
Solution:
stg.simuler(duree)
nbR = len(fp)
return ((nbP-nbR)/nbP,) + stg.criteres()
IP
(a) Charger la file des processus à partir du fichier texte "Processus.txt" (supposé existant).
IS
(b) Demander à l’utilisateur de saisir deux entiers positifs d et q décrivant respectivement
la durée totale de la simulation et le quantum à utiliser pour la méthode préemptive.
(c) Initialiser 3 Matrices mTermines, mTAM et mTRM (np.ndarray) ayant 3 lignes et d colonnes
où
— Chaque indice de ligne i représente une stratégie d’ordonnancement ( 0 pour FCFS,
1 pour SJF et 2 pour RR).
— Chaque indice de colonne j représente une durée totale de simulation (j+1) en cycles
d’horloge.
(d) La simulation se déroule comme suit :
— Pour chaque stratégie d’ordonnancement i (indice de ligne) et pour chaque indice
de colonne j.
— Copier la liste des processus dans un objet cfp (utiliser la fonction deepcopy du
module copy voir Annexe).
— Remplir mTermines, mTAMet mTRM à patir du résultat de la fonction simulerStrategie tel
que :
Solution:
BI
B-
IP
E IS
Solution: ou bien
— Dans notre contexte une gare ferroviaire de voyageurs est un lieu d’arrêt des trains pour
la montée et la descente des passagers.
— Une gare peut jouer le rôle d’arrêt, de départ et/ou arrêt transitoire et/ou arrêt de
terminus.
— Dans une gare de départ ou de terminus un train est mis au repos pendant un certain
nombre d’heures.
— Une ville peut contenir une ou plusieurs gares.
— Un voyage permet de desservir un ensemble de gares.
— Tout voyage par train doit nécessairement avoir une gare de départ, une gare de terminus
et éventuellement un ensemble de gares d’arrêts transitoires.
BI
Le schéma relationnel de la base de données ayant le nom "ferroviaire.db" est défini par
les relations suivantes :
La table Ville, stocke les différentes informations relatives aux villes, est caractérisée par
les attributs suivants :
— idVille : identifiant pour distinguer les différentes villes, clé primaire de type entier.
IP
■ Gare(idGare, nomGare,#idVille)
La table Gare, stocke les informations des gares, est caractérisée par les attributs suivants :
IS
■ Train(idTrain, dateMiseService,capacite)
La table Train, stocke les informations relatives aux trains, est caractérisée par :
— idTrain : identifiant du train, clé primaire de type chaîne de caractères.
— dateMiseService : date de mise en service du train, de type Date ("AAAA-MM-JJ")
— capacite : capacité d’accueil maximale du train, de type entier.
Travail demandé
E IS
Algèbre relationnelle
Q26. Donner les noms des villes qui contiennent des gares desservies par le voyage d’identifiant
"V23".
Solution:
Π
Ville ▷◁
idVille
Gare ▷◁ σ
idGare idGareArret idVoyage "V23"
(Desservir)
nomVille = =
Q27. Quels sont les noms des villes dont le nombre d’habitants dépasse 100000 et qui ne contiennent
aucune gare.
σ ▷◁
Π
nomVille nbHabitants>100000
(Ville)
idVille Π
idVille
(Ville) − Π
idVille
(Gare)
Ou bien
Π
nomVille
σ
nbHabitants
>100000
(Ville) − Π
nomVille
Ville ▷◁
idVille
Gare
SQL
Q28. Écrire la requête SQL qui permet de créer la table Desservir en respectant les contraintes
d’intégrité déjà su-citées. Les autres tables sont supposées déjà créées.
Solution:
BI
);
E
create table Desservir
(
idVoyage text,
IS
idGareArret text,
dateheurePassage datetime,
primary key(idVoyage,idGareArret),
foreign key(idVoyage) references Voyage(idVoyage),
foreign key(idGareArret) references Gare(idGare)
)
Dans la suite on suppose que les tables de la base de données sont remplies en respectant les
contraintes et les règles de gestion su-citées.
Q29. Si le train d’identifiant "TR77" circule le premier juin 2023 à 8h, déterminer toutes les
informations relatives à son voyage.
SELECT *
FROM Voyage
WHERE (idTrain = 'TR77')
AND (dateHeureDepart >= '2023-06-01 08:00:00')
AND (dateHeureArrivee <= '2023-06-01 08:00:00')
Solution:
/*Solution 1*/
E
ou bien
/*Solution 2*/
SELECT *
FROM Gare
WHERE IdGare IN
(
SELECT idGareDepart
FROM Voyage
WHERE idGareDepart = idGareTerminus
);
Solution:
Q33. Donner toutes les informations des voyages qui desservent le maximum de gares.
Solution:
BI
B-
IP
E IS
GROUP BY idVoyage
HAVING COUNT(*) > NBV
)
E
)
)
IS
SQLITE
Dans la suite les fonctions demandées doivent être écrites en Python en désignant par cur le
curseur d’exécution de requêtes.
Solution:
{('V01', 'TR10'):
[('GABES', 'GARE-GAB', '2023-01-15 11:15:00'),
E
Solution:
FROM Ville AS V,
Gare AS G,
Desservir AS D
E
WHERE (D.idVoyage = ?)
AND (D.idGareArret = G.idGare)
IS
Q36. Écrire la fonction circuitsVoyages qui prend en paramètre cur et retourne la liste des
dictionnaires des circuits de tous les voyages en faisant appel à la fonction circuitVoyage de
la question Q35. L’extrait qui suit montre un exemple :
Solution:
BI
def circuitsVoyages(cur):
q = """
B-
SELECT idVoyage
FROM Voyage
"""
cur.execute(q)
IP