Derniers messages sur Zeste de Savoirhttps://zestedesavoir.com/forums/2020-02-23T03:24:33+01:00Les derniers messages parus sur le forum de Zeste de Savoir.[Python] Multiplexage avec le module select, message #2161112020-02-23T03:24:33+01:00buffalo974/@buffalo974https://zestedesavoir.com/forums/sujet/13640/python-multiplexage-avec-le-module-select/?page=1#p216111<p>merci !</p>[Python] Multiplexage avec le module select, message #2159822020-02-20T09:37:25+01:00entwanne/@entwannehttps://zestedesavoir.com/forums/sujet/13640/python-multiplexage-avec-le-module-select/?page=1#p215982<figure><blockquote>
<p>Pour utiliser un chaque cœur d’un processeur multi-cœur, il faut soit lancer plusieurs programmes au niveau du système d’exploitation, soit <strong>lancer plusieurs threads au niveau d’un même programme</strong>.</p>
</blockquote><figcaption><a href="https://zestedesavoir.com/forums/sujet/13640/python-multiplexage-avec-le-module-select/?page=1#p215980">r0anne</a></figcaption></figure>
<p>À relativiser cependant en Python, puisqu’actuellement avec le <em><abbr title="Global Interpreter Lock">GIL</abbr></em> même si deux <em>threads</em> s’exécutent sur deux cœurs différents, ils ne le feront jamais simultanément.</p>[Python] Multiplexage avec le module select, message #2159802020-02-20T08:51:44+01:00r0anne/@r0annehttps://zestedesavoir.com/forums/sujet/13640/python-multiplexage-avec-le-module-select/?page=1#p215980<p>Salut,</p>
<p>À l’origine, il y a longtemps, les microprocesseurs disposaient d’un seul cœur, donc d’un seul « fil d’exécution » : un seul thread au niveau matériel. Les instructions étaient exécutées les unes après les autres :</p>
<div class="hljs-code-div"><div class="hljs-line-numbers"><span></span><span></span></div><pre><code class="hljs language-coq">| <span class="hljs-type">Instruction</span> <span class="hljs-number">1</span> | <span class="hljs-type">Instruction</span> <span class="hljs-number">2</span> | <span class="hljs-type">Instruction</span> <span class="hljs-number">3</span> | <span class="hljs-type">... |
======> Temps</span> ======>
</code></pre></div>
<p>Par la suite, et pour monter en performances plus facilement qu’en miniaturisant et rendant toujours plus puissants les microprocesseurs, on a décidé de mettre plusieurs microprocesseurs logiques les uns à côté des autres : c’est l’avènement du « multi-cœur ».</p>
<div class="hljs-code-div"><div class="hljs-line-numbers"><span></span><span></span><span></span><span></span></div><pre><code class="hljs language-gherkin"> /\
Cœurs ||<span class="hljs-string"> </span>|<span class="hljs-string"> Instruction 1 </span>|<span class="hljs-string"> Instruction 2 </span>|<span class="hljs-string"> Instruction 3 </span>|<span class="hljs-string"> ... </span>|
||<span class="hljs-string"> </span>|<span class="hljs-string"> Instruction 4 </span>|<span class="hljs-string"> Instruction 5 </span>|<span class="hljs-string"> Instruction 6 </span>|<span class="hljs-string"> ... </span>|
======> Temps ======>
</code></pre></div>
<p>Pour utiliser un chaque cœur d’un processeur multi-cœur, il faut soit lancer plusieurs programmes au niveau du système d’exploitation, soit <strong>lancer plusieurs threads au niveau d’un même programme</strong>.</p>
<p>Maintenant, imaginons que je veuille que mon programme écoute sur 10 sockets différentes. Logiquement, écouter sur un socket va bloquer mon programme, ou du moins 10 threads.</p>
<p>Si j’exécute plusieurs programmes et que mon système d’exploitation est multi-tâches, alors il va mutualiser le fil d’exécution du CPU entre différents programmes (si j’ai plus de programmes en exécution que de cœurs) :</p>
<div class="hljs-code-div"><div class="hljs-line-numbers"><span></span><span></span></div><pre><code class="hljs language-coq">| <span class="hljs-type">Instruction</span> <span class="hljs-number">1</span> programme A | <span class="hljs-type">Instruction</span> <span class="hljs-number">1</span> programme B | <span class="hljs-type">Instruction</span> <span class="hljs-number">2</span> programme A | <span class="hljs-type">... |
======> Temps</span> ======>
</code></pre></div>
<p>Il en est de même si j’ai différents threads (et que j’ai plus de threads en activité que de cœurs) :</p>
<div class="hljs-code-div"><div class="hljs-line-numbers"><span></span><span></span></div><pre><code class="hljs language-coq">| <span class="hljs-type">Instruction</span> <span class="hljs-number">1</span> thread A | <span class="hljs-type">Instruction</span> <span class="hljs-number">1</span> thread B | <span class="hljs-type">Instruction</span> <span class="hljs-number">2</span> thread B | <span class="hljs-type">... |
======> Temps</span> ======>
</code></pre></div>
<p>Maintenant, utiliser des threads a des inconvénients :</p>
<ul>
<li>
<p>Tu peux faire communiquer des threads entre eux, mais c’est compliqué. Ils risquent de se marcher sur les pieds : que se passe-t-il si l’un s’apprête à modifier deux variables liées entre elles à la suite, commence à en modifier une, mais que le second thread lit les deux variables sans que la deuxième variable n’ait encore été modifiée, et qu’il obtient des résultats contradictoires en conséquence ? La programmation avec les threads est plein de bugs tordus comme ça.<br>
<br>
Pour les éviter, il faut « bloquer » explicitement des zones du code qui touchent une même variable pour éviter qu’elles ne soient exécutées par deux programmes à la fois, c’est compliqué et ça créé des sacrés sacs de nœuds.<br>
</p>
</li>
<li>
<p>Les threads représentent un léger coût en performance et en mémoire. Il faut que le système les réveillent, les endorment, les réveillent… avec toutes les variables et le contexte qui vont avec à chaque fois. C’est pour ça que les serveurs qui sont utilisés pour de fortes nécessités de performances, comme Nginx, évitent d’utiliser des threads.</p>
</li>
</ul>
<p>Maintenant, quelle est l’alternative aux threads ? Les <strong>boucles événementielles</strong>. Le principe est simple : le programme se met d’accord avec le noyau pour écouter sur plusieurs sockets (ou plusieurs sockets + une entrée de terminal + un périphérique spécial, etc.) à la fois, et se faire réveiller par le noyau uniquement quand il y a de nouvelles données / un nouvel évènement à traiter.</p>
<p>Ainsi, il n’a <strong>qu’un seul fil d’exécution</strong> et qu’un seul état (et n’utilise qu’un seul cœur, sauf si tu commences à mettre une boucle événementielle sur chaque thread…).</p>
<p>Le module <code>select</code> permet d’utiliser une des API bas-niveau qui sont exposées par le noyau pour permettre des boucles événementielles sur plusieurs descripteurs (sockets, fichiers…), l’API <code>select</code>, disponible sur pratiquement toutes les plateformes. L’idée est donc que tu lui passes plusieurs sockets et que ton programme se fasse réveiller au bon moment. D’autres API plus récentes s’appellent <code>poll</code>, <code>epoll</code> (sous Linux) ou <code>kqueue</code> (sous FreeBSD), mais elles sont d’abord utilisées en C et ne sont pas disponibles sous toutes les plateformes.</p>
<p><code>asyncio</code> est une surcouche par-dessus ces différentes API qui te permettra d’utiliser ce qu’on appelle des <strong>coroutines</strong> : des fonctions qui te permettront d’avoir un programme avec un seul fil d’exécution et un seul état, mais chaque fonction s’endormira individuellement et repassera la main à la boucle évènementielle quand tu auras un appel bloquant (lecture, écriture… sur par exemple un socket) à faire. Ces appels sont préfixés par le mot-clef <code>await</code> dans les versions récentes Python, et les définitions de coroutines sont préfixées par le mot-clef <code>async</code>.</p>
<p>Les coroutines sont une des différentes approches pour faire ce qu’on appelle de l’asynchrone (intégrer proprement une boucle événementielle à ton programme). Une autre approche est celle des callbacks, utilisée par Node.JS (une autre fonction, en général imbriquée dans la première, sera appelée « à retardement » quand la boucle évènementielle aura retourné quelque chose). Il y a aussi des bibliothèques qui t’encouragent à faire des callbacks en Python, mais c’est moins fréquent.</p>
<p>Dans tous les cas, le module <code>select</code> est peu utilisé car c’est principalement une « brique » qui te permet d’accéder à une API bas-niveau, pour des besoins bas-niveau.</p>
<p>Bonne journée,</p>[Python] Multiplexage avec le module select, message #2159422020-02-19T21:52:30+01:00entwanne/@entwannehttps://zestedesavoir.com/forums/sujet/13640/python-multiplexage-avec-le-module-select/?page=1#p215942<p>C’est juste une technique différente.
Ça permet d’avoir des appels qui ne bloquent pas le <em>thread</em> courant et ça peut être utile quand on ne veut justement aps instacier de nouveaux <em>threads</em> et avoir à les gérer.</p>
<p>Par ailleurs, note que le module <a href="https://docs.python.org/3/library/selectors.html"><code>selectors</code></a> fournit une interface plus haut-niveau de <em>multiplexing</em>.
La page de documentation comporte aussi des exemples.</p>[Python] Multiplexage avec le module select, message #2159382020-02-19T21:18:43+01:00buffalo974/@buffalo974https://zestedesavoir.com/forums/sujet/13640/python-multiplexage-avec-le-module-select/?page=1#p215938<p>salut, qu’apporte le multiplexing avec le module select par rapport aux threads ?
auriez vous des exemples faciles à comprendre ?</p>Requête SQL sur deux table liée, message #1357582016-12-19T21:48:42+01:00viki53/@viki53https://zestedesavoir.com/forums/sujet/7599/requete-sql-sur-deux-table-liee/?page=1#p135758<p>L’idée est bien là. Fais juste attention à la différence entre <code>INNER</code> et <code>OUTER</code> suivant tes besoins <img alt=";)" src="/static/smileys/clin.png"> </p>Requête SQL sur deux table liée, message #1357202016-12-19T19:11:12+01:00Nemo/@Nemohttps://zestedesavoir.com/forums/sujet/7599/requete-sql-sur-deux-table-liee/?page=1#p135720<p>Je crois avoir réussi a concevoir ma requête, cela donnerait ceci:</p>
<div><table class="codehilitetable"><tr><td class="linenos"><div class="linenodiv"><pre>1</pre></div></td><td class="code"><div class="codehilite"><pre><span></span><span class="k">SELECT</span> <span class="n">NUTRIENTVALUE</span><span class="p">,</span> <span class="n">NUTRIENTNAME</span><span class="p">,</span> <span class="n">UNIT</span> <span class="k">FROM</span> <span class="n">NUTRIENT_AMOUNT</span> <span class="k">INNER</span> <span class="k">JOIN</span> <span class="n">NUTRIENT_NAME</span> <span class="k">ON</span> <span class="n">NUTRIENT_AMOUNT</span><span class="p">.</span><span class="n">NUTRIENTNAMEID</span> <span class="o">=</span> <span class="n">NUTRIENT_NAME</span><span class="p">.</span><span class="n">NUTRIENTNAMEID</span> <span class="k">WHERE</span> <span class="n">FOODID</span> <span class="o">=</span> <span class="o">?</span><span class="p">;</span>
</pre></div>
</td></tr></table></div>
<p>Est-ce que je fais erreur?</p>Requête SQL sur deux table liée, message #1357162016-12-19T18:45:54+01:00Nemo/@Nemohttps://zestedesavoir.com/forums/sujet/7599/requete-sql-sur-deux-table-liee/?page=1#p135716<p>Bonjour,
je suis vraiment rouillé en SQL et j’aurais besoin de votre aide pour concevoir un SELECT pour extraire toutes les valeurs NutrientValue d’une table associé à un FoodID en particulier de la table NUTRIENT_AMOUNT et que pour chaque enregistrement extrait, il contienne également les champs NutrientName et Unit de la table NUTRIENT_NAME auquels ils sont liés par le NutrientNameID.</p>
<p>Voici le détails des deux tables en question:</p>
<div><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">CREATE</span> <span class="k">TABLE</span> <span class="n">NUTRIENT_AMOUNT</span><span class="p">(</span><span class="n">FoodID</span> <span class="nb">INT</span> <span class="k">NOT</span> <span class="k">NULL</span><span class="p">,</span> <span class="n">NutrientNameID</span> <span class="nb">INT</span> <span class="k">NOT</span> <span class="k">NULL</span><span class="p">,</span> <span class="n">NutrientValue</span> <span class="nb">DECIMAL</span><span class="p">(</span><span class="mi">12</span><span class="p">,</span><span class="mi">5</span><span class="p">),</span> <span class="n">StandardError</span> <span class="nb">DECIMAL</span><span class="p">(</span><span class="mi">8</span><span class="p">,</span><span class="mi">4</span><span class="p">),</span> <span class="n">NumberOfObservations</span> <span class="nb">INT</span><span class="p">,</span> <span class="n">NutrientSourceID</span> <span class="n">LONG</span><span class="p">,</span> <span class="n">NutrientDateEntry</span> <span class="nb">DATE</span> <span class="p">);</span>
<span class="k">CREATE</span> <span class="k">TABLE</span> <span class="n">NUTRIENT_NAME</span><span class="p">(</span><span class="n">NutrientNameID</span> <span class="nb">INT</span> <span class="k">NOT</span> <span class="k">NULL</span><span class="p">,</span> <span class="n">NutrientCode</span> <span class="n">LONG</span> <span class="k">NOT</span> <span class="k">NULL</span><span class="p">,</span> <span class="n">NutrientSymbol</span> <span class="nb">VARCHAR</span><span class="p">(</span><span class="mi">10</span><span class="p">),</span> <span class="n">Unit</span> <span class="nb">VARCHAR</span><span class="p">(</span><span class="mi">8</span><span class="p">),</span> <span class="n">NutrientName</span> <span class="nb">VARCHAR</span><span class="p">(</span><span class="mi">200</span><span class="p">),</span> <span class="n">NutrientNameF</span> <span class="nb">VARCHAR</span><span class="p">(</span><span class="mi">200</span><span class="p">),</span> <span class="n">Tagname</span> <span class="nb">VARCHAR</span><span class="p">(</span><span class="mi">20</span><span class="p">),</span> <span class="n">NutrientDecimal</span> <span class="n">LONG</span><span class="p">);</span>
</pre></div>
</td></tr></table></div>
<p>Voilà, merci d’avance de votre aide!</p>Gérer plus que __FD_SETSIZE fd avec select, message #609842015-06-12T14:18:21+02:00entwanne/@entwannehttps://zestedesavoir.com/forums/sujet/3320/gerer-plus-que-__fd_setsize-fd-avec-select/?page=1#p60984<p>Il te faut voir aussi au niveau de ton système à combien est réglé le nombre max de <em>file descriptors</em> par processus.</p>
<figure><blockquote>
<p>et sinon, j'avais pensé divisé par 1024 chaques fd que je transmet aux macros FD_xxx et quand je les récupère je les remultiplies par le nombre de 1024 que j'avais enlevé, sauf que select utilise les macros donc ça peut pas marcher.
</p>
</blockquote>
<figcaption><p><a href="http://zestedesavoir.com/forums/sujet/3320/gerer-plus-que-__fd_setsize-fd-avec-select/?page=1#p60977">Krostar</a></p></figcaption></figure><p>Et surtout tu perds environ 3 chiffres.</p>Gérer plus que __FD_SETSIZE fd avec select, message #609772015-06-12T13:54:09+02:00Krostar/@Krostarhttps://zestedesavoir.com/forums/sujet/3320/gerer-plus-que-__fd_setsize-fd-avec-select/?page=1#p60977<p>J'ai résolu le problème peu après avoir posé la question, je reviens seulement maintenant pour en parler :</p>
<p>En effet, redéfinir __FD_SETSIZE permet de ne pas segve à cause de select avec plus de 1024 fd. Par contre, il faut (selon moi) procéder comme suit :</p>
<table class="codehilitetable"><tr><td class="linenos"><div class="linenodiv"><pre>1
2
3
4
5
6
7</pre></div></td><td class="code"><div class="codehilite"><pre><span class="cp">#include <sys/types.h> </span><span class="cm">/* fichier qui défini __FD_SETSIZE */</span><span class="cp"></span>
<span class="cp">#undef __FD_SETSIZE</span>
<span class="cp">#define __FD_SETSIZE 11264 </span><span class="cm">/* redefine à +de10K */</span><span class="cp"></span>
<span class="cm">/* includes demandés par select */</span>
<span class="cp">#include <unistd.h></span>
<span class="cp">#include <sys/select.h></span>
<span class="cp">#include <sys/time.h></span>
</pre></div>
</td></tr></table>
<p>et sinon, j'avais pensé divisé par 1024 chaques fd que je transmet aux macros FD_xxx et quand je les récupère je les remultiplies par le nombre de 1024 que j'avais enlevé, sauf que select utilise les macros donc ça peut pas marcher.</p>Gérer plus que __FD_SETSIZE fd avec select, message #598402015-06-04T17:59:55+02:00SimSonic/@SimSonichttps://zestedesavoir.com/forums/sujet/3320/gerer-plus-que-__fd_setsize-fd-avec-select/?page=1#p59840<p>J'étais curieux d'essayer, et il semble que l'on peut faire un <code>select</code> sur plus de 1024 descripteurs en redéfinissant <code>__FD_SETSIZE</code>. C'est laid, mais voici un petit example qui fonctionne sur ma machine au bureau (CentOS 6, glibc 2.12, GCC 4.4.7):</p>
<div class="spoiler">
<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
42
43
44
45</pre></div></td><td class="code"><div class="codehilite"><pre><span class="cp">#define _GNU_SOURCE</span>
<span class="cp">#include <fcntl.h></span>
<span class="cp">#include <stdbool.h></span>
<span class="cp">#include <stdio.h></span>
<span class="cp">#include <stdlib.h></span>
<span class="cp">#include <sys/resource.h></span>
<span class="cp">#include <sys/select.h></span>
<span class="cp">#include <sys/types.h></span>
<span class="cp">#define __FD_SETSIZE 2048</span>
<span class="cp">#define NUM_FDS 2000</span>
<span class="kt">int</span>
<span class="nf">main</span><span class="p">(</span><span class="kt">void</span><span class="p">)</span>
<span class="p">{</span>
<span class="kt">int</span> <span class="n">i</span><span class="p">,</span> <span class="n">fds</span><span class="p">[</span><span class="n">NUM_FDS</span><span class="p">];</span>
<span class="k">struct</span> <span class="n">rlimit</span> <span class="n">lim</span><span class="p">;</span>
<span class="n">lim</span><span class="p">.</span><span class="n">rlim_cur</span> <span class="o">=</span> <span class="n">__FD_SETSIZE</span><span class="p">;</span>
<span class="n">lim</span><span class="p">.</span><span class="n">rlim_max</span> <span class="o">=</span> <span class="n">__FD_SETSIZE</span><span class="p">;</span>
<span class="n">setrlimit</span><span class="p">(</span><span class="n">RLIMIT_NOFILE</span><span class="p">,</span> <span class="o">&</span><span class="n">lim</span><span class="p">);</span>
<span class="k">for</span> <span class="p">(</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">NUM_FDS</span><span class="p">;</span> <span class="n">i</span><span class="o">++</span><span class="p">)</span> <span class="p">{</span>
<span class="kt">char</span> <span class="o">*</span><span class="n">name</span><span class="p">;</span>
<span class="n">asprintf</span><span class="p">(</span><span class="o">&</span><span class="n">name</span><span class="p">,</span> <span class="s">"test%d"</span><span class="p">,</span> <span class="n">i</span><span class="p">);</span>
<span class="n">mkfifo</span><span class="p">(</span><span class="n">name</span><span class="p">,</span> <span class="n">S_IRUSR</span> <span class="o">|</span> <span class="n">S_IWUSR</span><span class="p">);</span>
<span class="n">fds</span><span class="p">[</span><span class="n">i</span><span class="p">]</span> <span class="o">=</span> <span class="n">open</span><span class="p">(</span><span class="n">name</span><span class="p">,</span> <span class="n">O_RDONLY</span> <span class="o">|</span> <span class="n">O_NONBLOCK</span><span class="p">);</span>
<span class="n">free</span><span class="p">(</span><span class="n">name</span><span class="p">);</span>
<span class="p">}</span>
<span class="n">fd_set</span> <span class="n">rset</span><span class="p">;</span>
<span class="n">FD_ZERO</span><span class="p">(</span><span class="o">&</span><span class="n">rset</span><span class="p">);</span>
<span class="k">for</span> <span class="p">(</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">NUM_FDS</span><span class="p">;</span> <span class="n">i</span><span class="o">++</span><span class="p">)</span>
<span class="n">FD_SET</span><span class="p">(</span><span class="n">fds</span><span class="p">[</span><span class="n">i</span><span class="p">],</span> <span class="o">&</span><span class="n">rset</span><span class="p">);</span>
<span class="n">select</span><span class="p">(</span><span class="n">NUM_FDS</span><span class="p">,</span> <span class="o">&</span><span class="n">rset</span><span class="p">,</span> <span class="nb">NULL</span><span class="p">,</span> <span class="nb">NULL</span><span class="p">,</span> <span class="nb">NULL</span><span class="p">);</span>
<span class="k">for</span> <span class="p">(</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">NUM_FDS</span><span class="p">;</span> <span class="n">i</span><span class="o">++</span><span class="p">)</span> <span class="p">{</span>
<span class="k">if</span> <span class="p">(</span><span class="n">FD_ISSET</span><span class="p">(</span><span class="n">fds</span><span class="p">[</span><span class="n">i</span><span class="p">],</span> <span class="o">&</span><span class="n">rset</span><span class="p">))</span>
<span class="n">printf</span><span class="p">(</span><span class="s">"Data available on FD %d.</span><span class="se">\n</span><span class="s">"</span><span class="p">,</span> <span class="n">fds</span><span class="p">[</span><span class="n">i</span><span class="p">]);</span>
<span class="p">}</span>
<span class="k">return</span> <span class="n">EXIT_SUCCESS</span><span class="p">;</span>
<span class="p">}</span>
</pre></div>
</td></tr></table>
<p>Et un petit test qui montre que ça fonctionne:</p>
<p><table class="codehilitetable"><tr><td class="linenos"><div class="linenodiv"><pre>1
2
3
4
5
6
7
8</pre></div></td><td class="code"><div class="codehilite"><pre><span class="gp">$</span> gcc test.c
<span class="gp">$</span> ./a.out <span class="p">&</span>
<span class="go">[1] 7725</span>
<span class="gp">$</span> <span class="nb">echo test</span> > test1344
<span class="gp">$</span> Data available on FD 1347.
<span class="go">[1]+ Done ./a.out</span>
<span class="gp">$</span>
</pre></div>
</td></tr></table>
</p>
</div>
<p>Par contre sur ma machine, seuls les processus privilégiés peuvent augmenter leur limite de descripteurs ouverts à plus de 4096. Donc cette solution ne marcherait pas pour un <code>select</code> sur 10000 descripteurs (sauf si le serveur roule avec la capabilité <code>CAP_SYS_RESOURCE</code>).</p>Gérer plus que __FD_SETSIZE fd avec select, message #597772015-06-04T05:41:39+02:00SimSonic/@SimSonichttps://zestedesavoir.com/forums/sujet/3320/gerer-plus-que-__fd_setsize-fd-avec-select/?page=1#p59777<figure><blockquote>
<p>Va pas y'avoir des problèmes si du code compilé dans la lib C dépend de la valeur antérieure FD_SETSIZE ?
</p>
</blockquote>
<figcaption><p><a href="http://zestedesavoir.com/forums/sujet/3320/gerer-plus-que-__fd_setsize-fd-avec-select/?page=1#p59774">Davidbrcz</a></p></figcaption></figure><p>Oui, en effet. Il semble par contre que <a href="https://sourceware.org/git/?p=glibc.git&a=search&h=HEAD&st=grep&s=FD_SETSIZE">ce ne soit pas le cas de glibc</a> (sauf sous Hurd). Les seules vérifications faites sur la valeur sont dans des fichiers inclus, et donc redéfinir la valeur de <code>__FD_SETSIZE</code> (et non <code>FD_SETSIZE</code>) après avoir inclut <code>sys/select.h</code> fonctionnerait <em>peut-être</em> (si en plus on augmente la limite de descripteurs ouverts du processus).</p>
<p>Cela dit, ça me semble une mauvaise idée de dépendre d'un détail d'implémentation de glibc. Une implémentation plus stricte pourrait très bien faire les vérifications directement dans son code compilé.</p>Gérer plus que __FD_SETSIZE fd avec select, message #597742015-06-04T02:35:38+02:00Davidbrcz/@Davidbrczhttps://zestedesavoir.com/forums/sujet/3320/gerer-plus-que-__fd_setsize-fd-avec-select/?page=1#p59774<p>Va pas y'avoir des problèmes si du code compilé dans la lib C dépend de la valeur antérieure FD_SETSIZE ? Par exemple, tu passes de 1024 à 2048 mais imagine que select fasse un check comme quoi l'index est inférieur à FD_SETSIZE (soit 1024 pour lui), ca coince.</p>
<p>Google me sort ca : <a href="https://stackoverflow.com/questions/7976388/increasing-limit-of-fd-setsize-and-select">https://stackoverflow.com/questions/7976388/increasing-limit-of-fd-setsize-and-select</a>
La réponse acceptée propose de faire une série de select à fenêtre tournante sur un tableau contenant le nombre d'éléments que tu veux (10 000 dans ton cas)</p>Gérer plus que __FD_SETSIZE fd avec select, message #597602015-06-03T22:34:27+02:00yoch/@yochhttps://zestedesavoir.com/forums/sujet/3320/gerer-plus-que-__fd_setsize-fd-avec-select/?page=1#p59760<p><code>FD_SETSIZE</code> est une macro, rien ne t'empêche de la redéfinir le temps de la compilation de ton programme. Il me semble que apache le fait, par exemple.</p>Gérer plus que __FD_SETSIZE fd avec select, message #597162015-06-03T18:06:20+02:00SimSonic/@SimSonichttps://zestedesavoir.com/forums/sujet/3320/gerer-plus-que-__fd_setsize-fd-avec-select/?page=1#p59716<figure><blockquote>
<p>J'ai eu plusieurs idées pour gérer le problème, mais toutes échoues.
</p>
</blockquote>
<figcaption><p><a href="http://zestedesavoir.com/forums/sujet/3320/gerer-plus-que-__fd_setsize-fd-avec-select/?page=1#p59686">Krostar</a></p></figcaption></figure><p>Pourrais-tu extrapoler là-dessus? Qu'est-ce que tu as déjà tenté? Pourquoi ça n'a pas fonctionné?</p>
<p>Ma première idée, si tu dois obligatoirement utiliser <code>select</code>, serait de simplement étaler les descripteurs sur 10 threads. Un seul appel à <code>select</code> ne peut peut-être pas gérer plus de 1024 descripteurs, mais rien n'empêche de faire 10 appels à <code>select</code> en parallèle (sous Linux du moins). Ça ne sera peut-être pas très performant, mais je crois que ça peut fonctionner.</p>
<p>Évidemment, pour que ça marche, il faut rehausser le limite de fichiers ouverts du processus serveur (avec <code>setrlimit</code> dans le programme, ou <code>ulimit</code> dans le <em>shell</em>).</p>Gérer plus que __FD_SETSIZE fd avec select, message #596862015-06-03T15:13:25+02:00Krostar/@Krostarhttps://zestedesavoir.com/forums/sujet/3320/gerer-plus-que-__fd_setsize-fd-avec-select/?page=1#p59686<p>Bonjour,</p>
<p>Dans le cadre d'un projet scolaire, je dois utiliser la fonction select sur un serveur pour gérer des clients.
Pour avoir des points bonus, je me suis porté volontaire pour gérer le "C10K Problem" avec select.</p>
<p>"The C10K Problem" est une problématique qui consiste à gérer 10 000 clients simultanés.
Le define __FD_SETSIZE vaut 1024, ce qui implique que select ne peux pas gérer plus que 1024 fd simultanéments.
Dans le man de select, il est spécifié que ce sont les macros FD_* qui ne gèrent pas ce problème, qui induit à segmentation fault.</p>
<p>J'ai eu plusieurs idées pour gérer le problème, mais toutes échoues.
Avez vous déjà eu ce genre de challenge, savez vous quels solutions pourraient être envisageables ?</p>
<p>Cordialement,
Krostar.</p>Write potentiellement bloquant après un select, message #505392015-04-06T18:04:15+02:00Krostar/@Krostarhttps://zestedesavoir.com/forums/sujet/2762/write-potentiellement-bloquant-apres-un-select/?page=1#p50539<p>Write me retournerai donc une taille différente que la taille de ma string, et ce moment là je pourrais fermer la connexion, pas bête.</p>
<p>Merci !
Si quelqu'un à une autre solution, je marque résolu en attendant <img alt=";)" src="/static/smileys/clin.png"></p>Write potentiellement bloquant après un select, message #505342015-04-06T17:19:45+02:00SimSonic/@SimSonichttps://zestedesavoir.com/forums/sujet/2762/write-potentiellement-bloquant-apres-un-select/?page=1#p50534<p>Ce n'est pas la solution que tu souhaites, mais tu peux éviter un blocage complet de ton write en utilisant l'option SO_SNDTIMEO sur le socket. Comme le nom l'indique, elle permet de spécifier un timeout sur les opérations d'écriture bloquantes.</p>Write potentiellement bloquant après un select, message #500962015-04-03T13:32:37+02:00Krostar/@Krostarhttps://zestedesavoir.com/forums/sujet/2762/write-potentiellement-bloquant-apres-un-select/?page=1#p50096<p>La question reste d'actualité du coups : ne serait-il pas plus simple de laisser à select le travail de regarder si je peux écrire ou pas (chose qu'il est censé faire beaucoup mieux que moi), et me contenter de vérifier si la taille du message que je veux écrire est inférieure à la taille que select m'autorise à écrire.</p>
<p>Puisque je ne peux pas savoir facilement, sans faire le travail de select, la taille que je peux écrire sur le buffer tcp, j'aimerais simplement récupérer une define ou truc du style, qui défini le seuil minimum à écrire pour que select considère que je peux le faire.</p>Write potentiellement bloquant après un select, message #500672015-04-03T00:28:51+02:00entwanne/@entwannehttps://zestedesavoir.com/forums/sujet/2762/write-potentiellement-bloquant-apres-un-select/?page=1#p50067<p>Si vraiment tu détectes que ton client ne répond plus (ça peut arriver si le réseau coupe par exemple), tu peux aussi choisir de le déconnecter. Reste à savoir comment tu détectes qu'il ne répond plus: sachant qu'un message de <em>ping</em> laisserait possible le cas du <code>write</code> bloquant, tu peux effectivement analyser la taille du contenu dans le buffer, et kicker le client si cette taille est trop importante.</p>
<p>Dans un projet «réel», la solution serait sûrement les écritures non bloquantes (et tout de même un système de <em>ping timeout</em> pour ne pas conserver un client mort), mais dans le cadre de ton projet scolaire, tu dois pouvoir t'en sortir comme ça.</p>Write potentiellement bloquant après un select, message #500512015-04-02T21:52:06+02:00Taurre/@Taurrehttps://zestedesavoir.com/forums/sujet/2762/write-potentiellement-bloquant-apres-un-select/?page=1#p50051<p>Salut,</p>
<p>La solution proposée par olzd semble faire double emploi de prime abord, mais ce n'est pas le cas. En spécifiant un descripteur comme non bloquant, tu évites les cas de blocage dû à une trop grande quantité de données à écrire (alors que <em>select</em> ne le permet visiblement pas).</p>