|
|
accès étudiants
|
Ecrire un programme C qui crée deux fils, l'un affiche les entiers de 1 à 50, l'autre de 51 à 100.
#include <stdio.h>
#include <stdlib.h>
#include <sys/types.h>
#include <unistd.h>
int main(void)
{ pid_t pid;
int i;
if ((pid = fork()) == -1)
{ perror("fork"); exit(1);
}
if (pid == 0)
{ /* fils1 */
for (i = 1; i <= 50; i++)
printf("%d\n", i);
return 0;
}
if ((pid = fork()) == -1)
{ perror("fork"); exit(1);
}
if (pid == 0)
{ /* fils2 */
for (i = 51; i <= 100; i++)
printf("%d\n", i);
return 0;
}
return 0;
}
Modifier le programme précédent pour que l'affichage soit 1 2...100.
Peut-être les nombres s'affichent déjà en ordre. Pour observer l'exécution asynchrone des deux fils, ajoutez une boucle de ralentissement, par exemple
#include <math.h>
#include <stdio.h>
#include <stdlib.h>
#include <sys/types.h>
#include <unistd.h>
int main(void)
{ pid_t pid;
int i, j;
double x = 123.456;
if ((pid = fork()) == -1)
{ perror("fork"); exit(1);
}
if (pid == 0)
{ /* fils1 */
for (i = 1; i <= 50; i++)
{ printf("%d\n", i);
for (j = 0; j < 100000; j++) x = exp(log(x));
}
return 0;
}
if ((pid = fork()) == -1)
{ perror("fork"); exit(1);
}
if (pid == 0)
{ /* fils2 */
for (i = 51; i <= 100; i++)
{ printf("%d\n", i);
for (j = 0; j < 100000; j++) x = exp(log(x));
}
return 0;
}
return 0;
}
L'affichage sera semblable
51 52 1 2 3 4 53 54 55 56 ... 46 47 96 97 98 99 48 49 50 100
Lancez le programme plusieurs fois et observez que l'ordre n'est pas toujours le même. Pourquoi ?
Pour synchroniser l'affichage, il suffit d'ajouter wait avant la crèation du second fils.
#include <math.h>
#include <stdio.h>
#include <stdlib.h>
#include <sys/types.h>
#include <unistd.h>
int main(void)
{ pid_t pid;
int i, j;
double x = 123.456;
if ((pid = fork()) == -1)
{ perror("fork"); exit(1);
}
if (pid == 0)
{ /* fils1 */
for (i = 1; i <= 50; i++)
{ printf("%d\n", i);
for (j = 0; j < 100000; j++) x = exp(log(x));
}
return 0;
}
wait(NULL);
if ((pid = fork()) == -1)
{ perror("fork"); exit(1);
}
if (pid == 0)
{ /* fils2 */
for (i = 51; i <= 100; i++)
{ printf("%d\n", i);
for (j = 0; j < 100000; j++) x = exp(log(x));
}
return 0;
}
return 0;
}
Ecrire un programme C permettant de lancer la commande passée en argument.
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
int main(int argc, char **argv)
{ if (argc < 2)
{ fprintf(stderr,"Usage: %s commande [arg] [arg] ...\n", argv[0]);
exit(1);
}
execvp(argv[1], argv + 1);
perror("execvp");
exit(1);
}
Exemples d'exécution
[stefan@ecrins tp]$ monexec ls -l /etc/httpd/conf.d/ total 36 -rw-r--r-- 1 root root 3424 Sep 2 2002 auth_pgsql.conf -rw-r--r-- 1 root root 814 Sep 3 2002 perl.conf -rw-r--r-- 1 root root 459 Sep 3 2002 php.conf -rw-r--r-- 1 root root 988 Sep 2 2002 python.conf -rw-r--r-- 1 root root 180 Sep 4 2002 README -rw-r--r-- 1 root root 251 Aug 6 2002 squirrelmail.conf -rw-r--r-- 1 root root 11140 Sep 4 2002 ssl.conf [stefan@ecrins tp]$ monexec echo a b a b [stefan@ecrins tp]$ monexec Usage: monexec commande [arg] [arg] ... [stefan@ecrins tp]$ monexec toto titi execvp: No such file or directory
Les commandes séparées par & s'exécutent simultanément.
#include<stdio.h>
#include <stdlib.h>
#include <sys/types.h>
#include <unistd.h>
int main(void)
{ pid_t pid;
if ((pid = fork()) == -1)
{ perror("fork"); exit(1);
}
if (pid == 0)
{ execlp("who", "who", NULL);
perror("execlp");
exit(1);
}
if ((pid = fork()) == -1)
{ perror("fork"); exit(1);
}
if (pid == 0)
{ execlp("ps", "ps", NULL);
perror("execlp");
exit(1);
}
execlp("ls", "ls", "-l", NULL);
perror("execlp");
exit(1);
}
Les commandes séparées par ; s'exécutent successivement.
#include<stdio.h>
#include <stdlib.h>
#include <sys/types.h>
#include <unistd.h>
int main(void)
{ pid_t pid;
if ((pid = fork()) == -1)
{ perror("fork"); exit(1);
}
if (pid == 0)
{ execlp("who", "who", NULL);
perror("execlp");
exit(1);
}
wait(NULL);
if ((pid = fork()) == -1)
{ perror("fork"); exit(1);
}
if (pid == 0)
{ execlp("ps", "ps", NULL);
perror("execlp");
exit(1);
}
wait(NULL);
execlp("ls", "ls", "-l", NULL);
perror("execlp");
exit(1);
}
Ecrire un programme C qui prend en paramètre une série de fichiers source .c, les compile chacun séparément et simultanément puis édite les liens pour produire un exécutable. Ce programme doit :
Envoyez votre programme ici. N'oubliez pas à préciser votre nom et prénom.