Derniers messages sur Zeste de Savoirhttps://zestedesavoir.com/forums/2016-06-22T13:05:38+02:00Les derniers messages parus sur le forum de Zeste de Savoir.Est-ce correct ?, message #1151452016-06-22T13:05:38+02:00anonyme/@anonymehttps://zestedesavoir.com/forums/sujet/6382/est-ce-correct/?page=1#p115145<p>Merci à vous deux, au final je crois que ce qui me posait problème, c'était le fait que les valeurs que prend <code>i</code> sont au final exactement les mêmes quel que soit le processus (père, fils, fils du fils, etc.) !</p>Est-ce correct ?, message #1151172016-06-22T10:23:56+02:00entwanne/@entwannehttps://zestedesavoir.com/forums/sujet/6382/est-ce-correct/?page=1#p115117<figure><blockquote>
<p>Merci mais ce qui m'intéresse surtout, c'est les différentes valeurs que <code>i</code> prend pour chaque processus. Car le processus nouvelle créé possède la même valeur de <code>i</code> que son parent (par définition du <code>fork</code>), puis il exécutera les instructions juste après le <code>fork</code> (donc l'incrémentation).</p>
</blockquote>
<figcaption><p><a href="https://zestedesavoir.com/forums/sujet/6382/est-ce-correct/?page=1#p115095">Lern-X</a></p></figcaption></figure><p>Sans <code>break</code>, tous les processus iront jusqu'à la fin de la boucle, donc <code>i</code> vaudra <code>N</code> dans chacun des processus en sortie de boucle.</p>
<p>Si tu veux connaître la valeur de <code>i</code> à la création du processus, elle sera de <span>$log_2(\lceil p\rceil)$</span>, avec <span>$p$</span> le rang de création du processus (même si cet ordre n'est pas forcément respecté en réalité, les valeurs resteront les mêmes : <span>$1$</span> pour le processus père, <span>$2$</span> pour son premier fils, <span>$3$</span> pour son second fils, <span>$4$</span> pour le premier fils de <span>$2$</span>, …).</p>Est-ce correct ?, message #1151012016-06-22T08:19:35+02:00ache/@achehttps://zestedesavoir.com/forums/sujet/6382/est-ce-correct/?page=1#p115101<p>Je ne comprend pas bien ton problème. Désolé si je réponds à coté.</p>
<p>Avec cette boucle, il y a 2 processus qui se crée avec i = 0 (le processus initial et son fils).<br>
Ensuite, pareil, 2 processus sont crée avec i = 1.<br>
Puis ensuite, 4 processus sont crée avec i = 2.<br>
Puis 8, … </p>
<p>Au final, on a bien :<span>$ 1 + \sum_{i=0}^{n-1}2^i = 2^{n} $</span> processus.</p>Est-ce correct ?, message #1150952016-06-22T00:23:24+02:00anonyme/@anonymehttps://zestedesavoir.com/forums/sujet/6382/est-ce-correct/?page=1#p115095<figure><blockquote>
<p>Avec un</p>
<table class="codehilitetable"><tr><td class="linenos"><div class="linenodiv"><pre>1
2</pre></div></td><td class="code"><div class="codehilite"><pre><span></span><span class="k">for</span> <span class="p">(</span><span class="kt">int</span> <span class="n">i</span> <span class="o">=</span> <span class="mi">0</span><span class="p">;</span> <span class="n">i</span> <span class="o"><</span> <span class="n">N</span><span class="p">;</span> <span class="n">i</span><span class="o">++</span><span class="p">)</span>
<span class="n">fork</span><span class="p">();</span>
</pre></div>
</td></tr></table>
<p>Tu obtiens <span>$2^N$</span> processus.</p>
<p>(Le processus père crée un nouveau fils, puis les 2 créent chacun un nouveau fils, les 4 chacun un fils, etc.)
</p>
</blockquote>
<figcaption><p><a href="https://zestedesavoir.com/forums/sujet/6382/est-ce-correct/?page=1#p115092">entwanne</a></p></figcaption></figure><p>Merci mais ce qui m'intéresse surtout, c'est les différentes valeurs que <code>i</code> prend pour chaque processus. Car le processus nouvelle créé possède la même valeur de <code>i</code> que son parent (par définition du <code>fork</code>), puis il exécutera les instructions juste après le <code>fork</code> (donc l'incrémentation).</p>Est-ce correct ?, message #1150922016-06-21T23:55:52+02:00entwanne/@entwannehttps://zestedesavoir.com/forums/sujet/6382/est-ce-correct/?page=1#p115092<p>Avec un</p>
<table class="codehilitetable"><tr><td class="linenos"><div class="linenodiv"><pre>1
2</pre></div></td><td class="code"><div class="codehilite"><pre><span></span><span class="k">for</span> <span class="p">(</span><span class="kt">int</span> <span class="n">i</span> <span class="o">=</span> <span class="mi">0</span><span class="p">;</span> <span class="n">i</span> <span class="o"><</span> <span class="n">N</span><span class="p">;</span> <span class="n">i</span><span class="o">++</span><span class="p">)</span>
<span class="n">fork</span><span class="p">();</span>
</pre></div>
</td></tr></table>
<p>Tu obtiens <span>$2^N$</span> processus.</p>
<p>(Le processus père crée un nouveau fils, puis les 2 créent chacun un nouveau fils, les 4 chacun un fils, etc.)</p>Est-ce correct ?, message #1150852016-06-21T23:07:14+02:00anonyme/@anonymehttps://zestedesavoir.com/forums/sujet/6382/est-ce-correct/?page=1#p115085<p>J'ai peur de m'être emmêlé les pinceaux…</p>Est-ce correct ?, message #1150782016-06-21T22:39:51+02:00anonyme/@anonymehttps://zestedesavoir.com/forums/sujet/6382/est-ce-correct/?page=1#p115078<p>Merci pour tes remarques, Berdes !</p>
<p>Sinon j'ai une question plus générale, qui concerne un <code>fork</code> dans une boucle, a priori je connais déjà la réponse (d'ailleurs je suis parti de ça pour écrire le code que j'ai mis dans l'OP).</p>
<p>Que se passe-t-il avec le code suivant :</p>
<table class="codehilitetable"><tr><td class="linenos"><div class="linenodiv"><pre>1
2
3
4</pre></div></td><td class="code"><div class="codehilite"><pre><span></span><span class="kt">int</span> <span class="n">i</span> <span class="o">=</span> <span class="mi">0</span><span class="p">;</span>
<span class="k">for</span> <span class="p">(</span><span class="n">i</span><span class="p">;</span> <span class="n">i</span> <span class="o"><</span> <span class="mi">2</span><span class="p">;</span> <span class="n">i</span><span class="o">++</span><span class="p">)</span> <span class="p">{</span>
<span class="n">fork</span><span class="p">();</span>
<span class="p">}</span>
</pre></div>
</td></tr></table>
<p>Si je ne me trompe pas :</p>
<ol>
<li>
<p>Le processus parent, noté A et pour lequel i = 0, crée un p-child A_B. Pour A_B, i = 0.</p>
</li>
<li>
<p>On arrive à la fin de la boucle, donc on a <code>i++</code>. Ainsi pour A et A_B, i = 1.</p>
</li>
<li>
<p>Nouvelle boucle.</p>
</li>
</ol>
<p>3.1. Le processus A, pour lequel i = 1, crée un p-child A_C. Pour A_C, i = 1.</p>
<p>3.2. Le processus A_B, pour lequel i = 1, crée un p-child A_B_Z. Pour A_B_Z, i = 1.</p>
<ol>
<li>On arrive à la fin de la boucle. Ainsi :</li>
</ol>
<p>4.1. Pour A, A_B, A_C et A_B_Z, i = 2.</p>
<p>EDIT : le markdown beugue pour l'avant-dernier point. J'a ibien écrit "4." et ça affiche "1.".</p>Est-ce correct ?, message #1150762016-06-21T22:30:03+02:00Berdes/@Berdeshttps://zestedesavoir.com/forums/sujet/6382/est-ce-correct/?page=1#p115076<p>Globalement, ça m'a l'air plutôt correct. Le seul gros défaut que je vois est ta deuxième condition <code>if(pid != 0)</code>. Ce que tu veux est plutôt un <code>else</code>. Non seulement, c'est plus clair, mais ça peut éviter des bugs particulièrement dur à comprendre si tu modifies <code>pid</code> dans ta première condition.</p>
<p>Un autre truc : quand tu affiches le contenu du fichier, tu affiches aussi EOF, ce qui n'est probablement pas ce que tu veux. Dans un cas comme ça, je te conseille d'écrire plutôt :</p>
<table class="codehilitetable"><tr><td class="linenos"><div class="linenodiv"><pre>1
2
3
4
5</pre></div></td><td class="code"><div class="codehilite"><pre><span></span><span class="kt">int</span> <span class="n">char_read</span> <span class="o">=</span> <span class="n">fgetc</span><span class="p">(</span><span class="n">file</span><span class="p">);</span>
<span class="k">while</span><span class="p">(</span><span class="n">char_read</span> <span class="o">!=</span> <span class="n">EOF</span><span class="p">)</span> <span class="p">{</span>
<span class="n">printf</span><span class="p">(</span><span class="s">"%c"</span><span class="p">,</span> <span class="n">char_read</span><span class="p">);</span>
<span class="n">char_read</span> <span class="o">=</span> <span class="n">fgetc</span><span class="p">(</span><span class="n">file</span><span class="p">);</span>
<span class="p">}</span>
</pre></div>
</td></tr></table>
<p>Au lieu d'utiliser <code>printf</code> pour afficher un unique caractère, <code>fputc</code> me semble plus adapté.</p>
<p>Une dernière remarque générale sur la manière de lire un fichier. Il est beaucoup plus efficace de lire plusieurs caractères à la fois via <code>fgets</code> et de l'afficher avec <code>fputs</code>. Cependant, cela nécessite de faire plus attention pour éviter de lire plus que ce que contient ton buffer.</p>
<p>Une dernière chose : dans tes commentaires, tu parles de 3 fichiers et de 4 process, sauf que ton programme peut fonctionner avec n'importe quel nombre de fichier. Pour moi, il faudrait soit vérifier que le nombre de fichier est le bon, soit éviter de donner ces nombres dans les commentaires.</p>Est-ce correct ?, message #1150732016-06-21T21:59:55+02:00anonyme/@anonymehttps://zestedesavoir.com/forums/sujet/6382/est-ce-correct/?page=1#p115073<p>Bonjour à tous,</p>
<p>Je n'ai pas de problème particulier avec le code que j'ai écrit (il compile et s'exécute correctement), mais je souhaiterais quand même avoir votre avis sur la qualité de celui-ci…</p>
<h3>Contexte</h3>
<p>On dispose de trois fichiers-texte A, B et C contenant respectivement les chaînes "contenu_a", "contenu_b" et "contenu_c". On passe le chemin absolu de chacun de ces fichiers à l'exécutable, grâce à la commande './exe chemin_a chemin_b chemin_c'.</p>
<p>Il faut que le programme affiche en parallèle sur la sortie standard leur contenu.<strong> Chaque fichier sera pris en charge par un processus distinct.</strong></p>
<h3>Ma solution (qui marche)</h3>
<p><em>… et qui est commentée.</em></p>
<table class="codehilitetable"><tr><td class="linenos"><div class="linenodiv"><pre> 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
28
29
30
31
32
33
34
35
36
37
38
39
40
41</pre></div></td><td class="code"><div class="codehilite"><pre><span></span><span class="kt">int</span> <span class="nf">main</span><span class="p">(</span><span class="kt">int</span> <span class="n">argc</span><span class="p">,</span> <span class="kt">char</span><span class="o">*</span> <span class="n">argv</span><span class="p">[])</span> <span class="p">{</span>
<span class="kt">pid_t</span> <span class="n">pid</span><span class="p">;</span> <span class="c1">// Contains either 0 (ie. : a process-child) or the process-ID of the last created process-child</span>
<span class="kt">int</span> <span class="n">i</span> <span class="o">=</span> <span class="mi">1</span><span class="p">;</span> <span class="c1">// Counts files (there are 3 files)</span>
<span class="k">for</span><span class="p">(</span><span class="n">i</span><span class="p">;</span> <span class="n">i</span> <span class="o"><</span> <span class="n">argc</span><span class="p">;</span> <span class="n">i</span><span class="o">++</span><span class="p">)</span> <span class="p">{</span>
<span class="n">pid</span> <span class="o">=</span> <span class="n">fork</span><span class="p">();</span> <span class="c1">// 3 processes are created</span>
<span class="k">if</span><span class="p">(</span><span class="n">pid</span> <span class="o">==</span> <span class="mi">0</span><span class="p">)</span> <span class="p">{</span> <span class="c1">// if it's a child, pid is set to 0 and the next instruction would be a new loop without this break. So we write this break ! Thus, children won't create processes.</span>
<span class="k">break</span><span class="p">;</span>
<span class="p">}</span>
<span class="p">}</span>
<span class="c1">// So now we have 4 processes : the parent + 3 children ones.</span>
<span class="k">if</span><span class="p">(</span><span class="n">pid</span> <span class="o">==</span> <span class="mi">0</span><span class="p">)</span> <span class="p">{</span> <span class="c1">// If the current process is a child one, we read and print its file's content (1 child is associated with 1 file because of the variable `i`)</span>
<span class="kt">FILE</span><span class="o">*</span> <span class="n">file</span> <span class="o">=</span> <span class="n">fopen</span><span class="p">(</span><span class="n">argv</span><span class="p">[</span><span class="n">i</span><span class="p">],</span> <span class="s">"r"</span><span class="p">);</span>
<span class="k">if</span><span class="p">(</span><span class="n">file</span> <span class="o">==</span> <span class="nb">NULL</span><span class="p">)</span> <span class="p">{</span>
<span class="n">perror</span><span class="p">(</span><span class="s">"Open"</span><span class="p">);</span>
<span class="k">return</span> <span class="o">-</span><span class="mi">1</span><span class="p">;</span>
<span class="p">}</span>
<span class="kt">int</span> <span class="n">char_read</span> <span class="o">=</span> <span class="mi">0</span><span class="p">;</span>
<span class="k">while</span><span class="p">(</span><span class="n">char_read</span> <span class="o">!=</span> <span class="n">EOF</span><span class="p">)</span> <span class="p">{</span>
<span class="n">char_read</span> <span class="o">=</span> <span class="n">fgetc</span><span class="p">(</span><span class="n">file</span><span class="p">);</span>
<span class="n">printf</span><span class="p">(</span><span class="s">"%c"</span><span class="p">,</span> <span class="n">char_read</span><span class="p">);</span>
<span class="p">}</span>
<span class="k">if</span><span class="p">(</span><span class="n">fclose</span><span class="p">(</span><span class="n">file</span><span class="p">)</span> <span class="o">!=</span> <span class="mi">0</span><span class="p">)</span> <span class="p">{</span>
<span class="n">perror</span><span class="p">(</span><span class="s">"Close"</span><span class="p">);</span>
<span class="k">return</span> <span class="o">-</span><span class="mi">2</span><span class="p">;</span>
<span class="p">}</span>
<span class="n">printf</span><span class="p">(</span><span class="s">"</span><span class="se">\n\n</span><span class="s">"</span><span class="p">);</span>
<span class="p">}</span>
<span class="k">if</span><span class="p">(</span><span class="n">pid</span> <span class="o">!=</span> <span class="mi">0</span><span class="p">)</span> <span class="p">{</span> <span class="c1">// If we are the parent process, we wait for its children ones' ending</span>
<span class="n">wait</span><span class="p">(</span><span class="nb">NULL</span><span class="p">);</span>
<span class="p">}</span>
<span class="k">return</span> <span class="mi">0</span><span class="p">;</span>
<span class="p">}</span>
</pre></div>
</td></tr></table>
<h3>Ma question</h3>
<p>Donc comme je l'ai déjà dit, ce code compile, s'exécute et fait bien ce qu'on lui demande.</p>
<p>Cependant, avez-vous des remarques à faire ? Notamment, le <code>break</code> et sa condition vous paraissent-ils OK ? Est-ce que les développeurs C procéderaient bien de cette manière ou ma solution est un peu "exotique/originale" ?</p>
<p>Voilà voilà, merci d'avance, bonne soirée à vous. <img alt=":)" src="/static/smileys/smile.png"></p>