Petit probleme de récursivité entre deux appels de sub - VB/VBA/VBS - Programmation
Marsh Posté le 08-12-2005 à 15:25:32
Voila un schéma trés simplifié de ce que ça donne dans l'appli complete :
Une requete cliente >> appelle une fonction qui lit x octets d'un fichier >> qui l'envoie sur le socket >> qui une fois terminé (socket_complete) >> appel la fonction qui lit x octets d'un fichier >> qui l'envoie sur le socket >> ....... >> et arrete le tout lorsque la fin du fichier est atteint
En clair c'est récursif mais comme dans le bout de code plus haut, le code présent après les appels de sub est ignoré (il reste en attente) et au bout d'un moment la pile déborde... puis c'est le drame!
Comment passer d'un appel à l'autre sans accumuler les fonction 'presque' fini initilement en mémoire?
Marsh Posté le 08-12-2005 à 17:36:06
Refait tes fonctions pour ne pas faire d'appels réucrsifs
Marsh Posté le 08-12-2005 à 18:36:59
j'ai oublié comment ca marche vb, mais je verrai ca plutot dans une boulce que comme tu le fais.
ouvrir le fichier
lire une ligne
tant qu'on n'est pas à la fin du fichier
{
envoyer la ligne
lire une ligne
}
Marsh Posté le 08-12-2005 à 21:05:45
Le problème avec une boucle c'est que sur un long transfert, la boucle doit tourner en permanance en vérifiant si le socket a terminé l'envoi de ce qu'on lui a demandé d'envoyer afin de lire la suite dans le fichier et de l'envoyer au socket.
Avant j'avais un timer qui faisait sans problème : socket_complete mettait true à une variable et une fois que le timer passait sur cette variable à true il envoyait la suite, mais c'était terriblement lent pour envoyer des centaines de mo, même a interval de 1ms.
Marsh Posté le 08-12-2005 à 21:12:24
art_dupond a écrit : j'ai oublié comment ca marche vb, mais je verrai ca plutot dans une boulce que comme tu le fais. |
Dans cet exemple sur un fichier de 2go, tout est mis en mémoire et envoyé directement au socket, c'est assez bourrin . socket_complete (la fonction événement appelée par le socket à la fin de l'envoi) doit intervenir pour dire quand on peut envoyer la suite, quand il est libre... à moins d'avoir beaucoup de mémoire
Marsh Posté le 08-12-2005 à 21:23:46
c'est quoi le problème avec la boucle, j'ai pas bien pigé
suffit de mettre un DoEvents avant de faire le loop...
Marsh Posté le 08-12-2005 à 21:46:33
Arjuna a écrit : c'est quoi le problème avec la boucle, j'ai pas bien pigé |
oui mais dans ce cas le proc tourne à 99% même avec un doevent (encore pour un seul transfert) alors que dans le cas de subs qui s'appellent il n'y a aucune surcharge du cpu, le seul souci est le dépassement de piles
Marsh Posté le 08-12-2005 à 22:02:16
un truc comme ca peut etre (me rappelle vraiment pas bien, je ne sais pas si ca marcherait)
Code :
|
pas taper si c'est mal
Marsh Posté le 08-12-2005 à 22:22:50
art_dupond a écrit : un truc comme ca peut etre (me rappelle vraiment pas bien, je ne sais pas si ca marcherait)
|
Je ne pense pas qu'il reussisse à revenir dans la boucle juste en faisant un saut de ligne, mais le probleme c'est que ça fait toujours appel à une boucle et donc à une grosse charge cpu (rien que pour un seul transfert). Avec les trois subs qui s'appellent les uns les autres (et qui font un beau dépassement de pile ) il n'y a aucune charge cpu.
Marsh Posté le 08-12-2005 à 23:55:35
comme ca alors ?
Code :
|
sinon tu peux expliquer pourquoi une boucle entraine une grosses charge cpu (c'est une question) ?
ps: désolé si je propose des bêtes solutions...
Marsh Posté le 09-12-2005 à 01:21:29
comme art_dupond : je suis perplexe quant à la charge de 100% à cause de la boucle...
m'enfin le plus simple serait peut-être simplement de passer à un autre langage pour écrire une DLL qui s'occupe des transfert si vraiment ça marche pas.
Marsh Posté le 09-12-2005 à 01:41:02
art_dupond a écrit : comme ca alors ?
|
c'est pas des solutions bêtes et merci déjà de répondre
on parle peut être pas du même type de boucle :
une boucle :
Code :
|
me pompe 99% de mon cpu pendant qu'elle tourne, d'ailleur une boucle while contenant qu'un doevents : idem
Marsh Posté le 09-12-2005 à 10:43:19
fils_de_la_lumiere a écrit : oui mais dans ce cas le proc tourne à 99% même avec un doevent (encore pour un seul transfert) alors que dans le cas de subs qui s'appellent il n'y a aucune surcharge du cpu, le seul souci est le dépassement de piles |
Quand tu fais une boucle avec un doevents, le CPU est indiqué comme étant utilisé à 100% mais ça ne gène pas l'execution des autres programmes.
Marsh Posté le 09-12-2005 à 10:46:16
tu t'en fout de ça. ça bouffe 100% du CPU, mais c'est de la charge qui ne consomme pas si je puis dire. seul "doevents" fait quelquechose dans cette boucle, hors il laisse la place aux autres processus si besoin. donc que le CPU soit à 100% ou 0%, la dispoibilité du cpu reste la même pour les autres programmes.
Marsh Posté le 09-12-2005 à 18:54:55
Moi quand je fait une boucle avec un doevents tout seul au bout d'un moment ça se ressent sur la température de mon cpu. Je connais pas de programme utilisant 99% du cpu (même fictivement) rien que pour transférer un fichier à 5ko/sec Je trouve pas ça trés clean de tester en permanence si une condition est remplie pour continuer à envoyer des données (c'est pourtant ce que je faisais avec un timer mais avec une boucle c'est encore moins clean). Je pense que le socket doit avertir activement (comme dans l'exemple du deuxième poste) du fait qu'il ait fini d'envoyé en appelant de lui même une sub et non passivement (la fin d'envoi met une variable à true sur lequel une boucle ou timer fait un test discontinue).
Marsh Posté le 09-12-2005 à 20:04:37
pour ça, il faut coder multithread, mais VBS ne le permet pas (VB non plus d'ailleurs)
Seul truc que tu peux faire, comme je t'ai dit, c'est utiliser une DLL écrite dans un autre langage, qui elle s'occuper de threader le tranfsert, et ne te redonne la main que lorsqu'elle a terminé (ou alors tu la laisse tourner en tâche de fond, et tu la butte quand tu t'apperçois qu'elle a fini, mais c'est un peu plus compliqué à faire)
Marsh Posté le 07-12-2005 à 19:08:32
Bonjour, j'ai un petit souci avec deux subs qui s'appellent mutuellement dans le code ci-dessous. Une erreur de type StackOverflow (Err 28 : Espace de pile insufisant) arrête l'application au bout d'une dizaine de seconde. Connaisseriez vous un appel spécial demandant de terminer sub2 en appelant sub1 afin de permettre de pas accumuler ces fonctions dans la mémoire.