compter les threads et tasks (Résolu)
Genose
Membre
Salut;
Existe il un moyen déjà existant dans Objective-c/cocoa, pour compter les threads et task instancié qu'ils soit actif ou non dans mon appli afin d'acceder séparement à ceux-ci, ou alors faut-il impérativement que je personalise les nsthreads et nstasks d'une catégorie ?
merci de vos lumiéres.
Existe il un moyen déjà existant dans Objective-c/cocoa, pour compter les threads et task instancié qu'ils soit actif ou non dans mon appli afin d'acceder séparement à ceux-ci, ou alors faut-il impérativement que je personalise les nsthreads et nstasks d'une catégorie ?
merci de vos lumiéres.
Connectez-vous ou Inscrivez-vous pour répondre.
Réponses
Tu t'es vraiment relu ?
Et tu crois qu'on va comprendre ce que tu demandes ?
.
.
oui, c'est une solution, mais en terme de puissance requise ça me semble un peu long pour un vieux mac, (G3), et là , sa devient complexe puisque aprés il faut faire (n-2) résultats.
je tente les catégories mais ce n'est pas facile avec ces classes là .
.
int nbtask = [NSTask count];
int nbthread = [NSThread count];
Les tasks et les threads créés par ton appli, ou par toutes les applis ?
.
non, non, je parlais bien des threads et task faites par mon appli .
Ben alors, pourquoi ne fais-tu pas le comptage toi-même à chaque fois que tu créés (ou instancies) une tâche/thread ?
.
Tu peux mettre un static int que tu in/decrémente à la destruction/création d'un thread...
;D ;D ;D ;D ;D ;D ;D
ha ! parce que toi tu irais faire tes ++ ou -- pour chaque fois que fait un threads et sans sous classe ?
j'ai mieux que ça !!
car je doit y acceder depuis n'importe où dans l'appli et sans inconvention (pas de sous classe et pas de blablamethode).
les catégories.
et ça passe plutôt bien, je doit encore mettre le initialize et release et ne restera plus que à tester .
je vous passerais le resultat (si/quand) tout fonctionne.
Je pense pas qu'il y ait plus simple et plus rapide...
mais là moi nan je fait un truc qui fonctionne tout seul, et la preuve :
un truc sendmsg ou selector et voila
tien je vient de m'apercevoir que avec mon truc, je vient ,sans fumer de creer une méthode d'acces à tout les threads et task de mon appli . :fouf):
c'est mon API qui prend alors forme et puissance. :kicking:
voila j'ai réussi mon tour de passe -passe, résultats en images
merci de vous être attrouper au probleme, je crois que je vais faire une NSView spécialement sur Objective-Cocoa.org dans mon appli, dans les "contributors", plutôt qu'une ligne.
je mais quand même un ©copyright sur cette idée, si je peux me permettre,
y'a pas de sous-classes, pas de #define pour jouer les macros qui font croire à une classe normale pendant la compilation et faire peut etre des bugs pendant la création avec la méme classe à l'execution d'un objet.
merci.
[Fichier joint supprimé par l'administrateur]
A moins qu'en l'appelant sur l'objet classe et non sur l'objet instance de classe ? Tiens je ne sais pas comment ça réagit de ce côté là un [NSTask retainCount] mais bon je sais pas si c'est très propre.
En tout cas si tu crées 3 variables distinctes de type NSTask toutes les 3, et donc qu'en utilisant ces variables tu crées 3 tasks, et bien le retainCount de chacune des variables sera à 1, et non à 3 : ce sera bien 3 tasks différentes, et 3 variables pointant sur des NSTask différents, donc le retainCount de chacune sera indépendant des autres. Et tu ne pourras pas utiliser [monInstance retainCount] pour avoir le nombre total de NSTask créées dans ton programme !
Pareil si tu crées 5 threads indépendants faisant chacun un bout de code (je veux dire pas 5 variables pointant sur le même thread avec un retain pour chaque), le retainCount ne va pas te servir à grand chose...
Mais j'y pense : l'utilitaire "ps" en ligne de commande sait bien retourner ce genre d'infos, non ? C'est que ça doit être qqpart
La méthode retainCount est là pour procéder au recensement de tes objets, et je ne vois pas d'exception d'utilisation dans la doc. Prenons par exemple le code suivant, implémenté dans une classe demandant un recensement de ces tasks.
[tt]
-(void)awakeFromNib
{
task1=[[NSTask alloc] init];
task2=[[NSTask alloc] init];
task3=[[NSTask alloc] init];
}
// Méthode accesseur
-(unsigned)totalCountTasks
{
return ([task1 retainCount]+[task2 retainCount]+[task3 retainCount]);
}
[/tt]
Qu'est-ce qui n'irait pas dans ce code ?
Sans compter que se baser sur la valeur du retainCount est à mon sens une erreur, dans la mesure où il peut varier en cours d'exécution du programme, même dans un environnement que tu penses controller. Enfin, plus exactement, sachant qu'il y a des cas où il peut varier sans intervention, je préfère prendre ça comme règle, même si pour les NSTask ce n'est peut-être pas fondé.
Oui, c'est juste pour le principe et l'exemple, c'est certain qu'il manque les release et d'autres choses.
Là je ne suis pas au courant, et dans quels cas le retainCount peut varier sans notre intervention ? Vu que c'est nous qui sommes responsable de la création et libération de l'objet, il ne va quand même pas se libérer tout seul ? Et si le système venait à faire un retain dessus, il suffit, avant de la renvoyer, de limiter la valeur du retainCount à 1 si elle lui est supérieure ?
1) Le retainCount d'une variable de type NSTask n'indique nullement le nombre de tâches ou encore le nombre de fois que cette task est lancée
2) Pour connaà®tre le nombre de tâches adns ton programme, avec ta méthode, il faut additionner le retainCount (ou autre chose) de toutes tes variables de type NSTask... Si un jour tu rajoutes une NSTask dans ton programme, il faudra aussi modifier alors la méthode qui compte pour rajouter cette variable...
C'est pas du tout le but, surtout que si tu sais que tu as 5 variables de type NSTask dans ton programme, ben tu sais que tu as au plus 5 tâches (et encore, mais bon). Mais si tu connais les variables de type NSTask que tu as c'est "plus du jeu", le but n'est pas là
Exemple pour étayer le point 1 : Là tu as un peu de tout :
- d'une part t1 et t3 pointent sur la même NSTask : juste après la ligne "t3 = t1;", le retainCount de la tâche t1 (qui est la même que la tâche t3) est de 2... Donc déjà , si tu fais [t1 retainCount]+[t2 retainCount]+[t3 retainCount] tu obtiendras 4 et non pas 3
- d'autre part en mettant tes tâches t1 et t2 dans un tableau, elles sont automatiquement "retainées" par le tableau. donc le retainCount de t1 et de t2 augmente encore de 1 !
Au final si je fais executer une tâche à la NSTask t1 ainsi qu'à la NSTask t2 (avec setLaunchPath, etc, puis launch), j'aurais 2 NSTask dans mon programme, pourtant ta formule d'addition des retainCount de t1,t2 et t3 donnerait 3+2+3 (t1=t3=tab[0] donc retenu 3 fois, et t2=tab[1] donc retenu 2 fois) ou même 3+2 si tu n'additionne que les retainCount de t1 et t2... dans tous les cas ça donne des résultats complètement faux Ou plus exactement pas du tout les résultats que tu pouvais attendre.
Le retainCount d'une NSTask (d'un NSObject en général) n'est pas du tout représentatif du nombre d'objets de ce type créés en mémoire, mais bien du nombre de variables qui pointent vers l'objet pour lequel on demande le retainCount. Et la question est pas de savoir combien de pointeurs pour un objet particulier de type NSTask, mais bien combien d'objets de type NSTask sont en mémoire :d
Après, il est de la responsabilité de l'objet de se libérer si le retainCount devient 0. Mais le programmeur ne libère jamais lui même un objet (sauf très rares exceptions).
Prenons par exemple une NSString que tu crées (+1) et tu la mets dans un tableau (+1). Une fois dans le tableau, pour respecter la règle, tu la releases (-1). Arrive le moment où la valeur de la string est récupérée par une NSCell qui doit la dessiner (+1). Une fois dessinée, la cell la release (-1) et passe à une autre string. Et je crois que si on s'amuse avec les bindings, le schéma va encore se compliquer bigrement.
Donc tout ça pour dire qu'une fois qu'un objet est créé, tu ne contrôles pas forcément son retain count. La seule garantie que tu as en faisant un retain (ou un alloc) c'est que l'objet ne sera pas libéré, parce que tu as la responsabilité de faire le release correspondant au moment que tu juges opportun, mais rien ne te donne la garantie que c'est au "release correspondant" que l'objet sera libéré. Donc non, l'objet ne se libérera jamais tout seul, mais il peut être retenu ailleurs. Dans ton exemple, il serait donc parfaitement envisageable que 3 soit renvoyé, alors qu'une seule des tâches existe.
Quant à surchager la méthode pour qu'elle revoie 1 si le retaincount est supérieur à 1, c'est vraiment du bricolage. Au premier release (peu importe le nombre de retain qu'il y aurait eu avant), l'objet sera libéré. Ou bien alors il faut surcharger release pour release ne tienne pas compte de [self retainCount], mais de de [super retainCount].
Bon je suis d'accord pour dire que dans la réalité tout n'est pas aussi tranché que je dis là . Il est évident que pour bon nombre d'objets on a un contrôle "total", mais il vaut mieux à mon sens considérer les cas les plus "restrictifs", cela permet d'éviter des ennuis. En particulier si après 1 mois, on oublie qu'on ne peut pas faire de retain sur task1 parce que le retainCount est utilisé dans une méthode et doit surtout rester égal à 1 sinon crash. En fait pour l'exemple que tu donnes, le plus simple (et de loin!) serait de stocker les NSTask dans un tableau, et renvoyer la taille du tableau.
Non non, le retainCount sera de 2. En faisant [tt]t3 = [t1 retain];[/tt] il sera égal à 3, mais certainement pas à 4 (mais ce sera le cas après ajout dans le tableau pour ton code).
Mais le simple fait de définir un pointeur ne fait pas varier le retainCount (on est pas en Java ici).
En plus je suis au courant de toutes ces règles, mais c'est vrai que si l'objet est fortement sollicité, ça devient ingérable et alors là ça tombe carrément à l'eau. Je comprend mieux maintenant, mais ce n'est pas tout à fait là que je voulais en arriver...
[EDIT]
Non, ce n'est pas ce que je voulais dire. Bien sûr que le cas que tu décris est un ignoble bricolage.;)
Je voulais dire, en prenant mon code plus haut, faire un truc du style :
[tt]
-(unsigned)totalCountTasks
{
   unsigned t1,t2,t3;
   t1=t2=t3=0;
   if ([task1 retainCount]>0)
   {
     t1=1;
   }
   if ([task2 retainCount]>0)
   {
     t2=1;
   }
   if ([task3 retainCount]>0)
   {
     t3=1;
   }
   return (t1+t2+t3);
}[/tt]
Je partais du principe que si le retainCount n'est pas nul, alors c'est que l'objet existe.
Enfin ça répond pas au problème initial permettant de compter les threads ou les tasks, car dans le problème initial on ne connaà®t même pas les variables, on veut compter toutes les Task de notre programme sans avoir besoin de connaà®tre les noms des variables qui contiennent les instances, et même d'ailleurs si ces dernières ne sont pas accessibles (car dans un autre Thread par exemple, ou à l'intérieur d'un objet dont on n'a pas accès...)
Parce que si tu connais le nom des variables que tu utilises pour gérer tes NSTasks, c'est facile, il suffit de compter le nombre de ces variables qui sont instanciées, comme on a fait justement dans les derniers posts... mais si tu ne connais pas leur nom ou veux faire un truc plus générique...
Moi j'aurais essayé du côté de la surcharge des méthodes appelées lors de la création et de la destruction d'une NSTask (initialize et dealloc ?), qui aurait incrémenté et décrémenté un compteur global... Maintenant je ne sais pas quelle solution Genose a fini par choisir
[Arg mon premier avis de grillade :P]
-(unsigned)totalCountTasks
{
  unsigned t1,t2,t3;
  t1=t2=t3=0;
  if (task1)
  {
     t1=1;
  }
  if (task2)
  {
     t2=1;
  }
  if (task3)
  {
     t3=1;
  }
  return (t1+t2+t3);
}
Voilà .
Ha j'ai droit à l'avertisseur de grillade :P, donc je vais ajouter en lisant le message d'Ali que effectivement, pour des cas plus complexes ce n'est pas le mieux...enfin bon j'ai dit ce que j'avais à dire.:)