compter les threads et tasks (Résolu)

GenoseGenose Membre
novembre 2005 modifié dans API AppKit #1
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.

Réponses

  • BruBru Membre
    15:45 modifié #2
    dans 1131723685:

    existe il un moyen de compter les threads et task ou alors faut-il impérativement que je peronalise les threads et tasks d'une catégorie ?


    Tu t'es vraiment relu ?
    Et tu crois qu'on va comprendre ce que tu demandes ?

    .
  • GenoseGenose Membre
    15:45 modifié #3
    ca devrais être plus lisible, désolé.
  • 15:45 modifié #4
    Non, de la même manière qu'il n'existe pas de méthode pour compter le nombre de NSDictionary dans un application. Par contre, si tu dois juste compter, il doit exister des fonctions de plus bas niveau, mais je ne les connais pas.
  • BruBru Membre
    15:45 modifié #5
    Une solution est d'utiliser un NSTask qui lance la commande ps, puis de récupérer le résultat et compter.

    .
  • GenoseGenose Membre
    15:45 modifié #6
    dans 1131730320:

    Une solution est d'utiliser un NSTask qui lance la commande ps, puis de récupérer le résultat et compter.

    .



    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à .
  • BruBru Membre
    15:45 modifié #7
    Que veux tu faire exactement ?

    .
  • GenoseGenose Membre
    15:45 modifié #8
    je cherche comme donné:

    int nbtask = [NSTask count];

    int nbthread = [NSThread count];

    ;)
  • BruBru Membre
    15:45 modifié #9
    dans 1131742553:

    je cherche comme donné:
    int nbtask = [NSTask count];
    int nbthread = [NSThread count];


    Les tasks et les threads créés par ton appli, ou par toutes les applis ?

    .
  • GenoseGenose Membre
    novembre 2005 modifié #10
    dans 1131742553:


    pour compter les threads et task instancié qu'ils soit  actif ou non dans mon appli afin d'acceder séparement à  ceux-ci




    non, non, je parlais bien des threads et task faites par mon appli .
  • BruBru Membre
    15:45 modifié #11
    dans 1131743849:

    dans 1131742553:

    pour compter les threads et task instancié qu'ils soit  actif ou non dans mon appli afin d'acceder séparement à  ceux-ci

    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 ?

    .
  • 15:45 modifié #12
    Salut,

    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
  • GenoseGenose Membre
    15:45 modifié #13
    dans 1131744441:

    Salut,

    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.
  • 15:45 modifié #14
    Bein ouiai, tu peux y acceder sans problème.
    Je pense pas qu'il y ait plus simple et plus rapide...
  • GenoseGenose Membre
    15:45 modifié #15
    ouai je comprend comment tu fait,mais faut suivre le code aprés si tu release plus loin.

    mais là  moi nan :o je fait un truc qui fonctionne tout seul, et la preuve :

    <br /><br /><br />2005-11-11 22:48:37.770 myapp[2869]&nbsp; cool ca focntionne : threads initialize<br />2005-11-11 22:48:37.770 myapp[2869] *** +[NSThread _Thread_initialize_method]: selector not recognized<br /><br />
    


    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:

  • GenoseGenose Membre
    15:45 modifié #16
    bonsoir,


    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]
  • Eddy58Eddy58 Membre
    novembre 2005 modifié #17
    Je ne sais pas comment tu as procédé exactement, mais il y a la méthode "retainCount" qui est faites pour ce genre de choses. Pour faire les choses proprement, j'aurais implémenté dans chaque classe un accesseur qui retourne les retains count voulu, puis relié ces classes à  la classe qui recueille le comptage de tes instances. :)
  • AliGatorAliGator Membre, Modérateur
    15:45 modifié #18
    dans 1131971353:

    Je ne sais pas comment tu as procédé exactement, mais il y a la méthode "retainCount" qui est faites pour ce genre de choses. Pour faire les choses proprement, j'aurais implémenté dans chaque classe un accesseur qui retourne les retains count voulu, puis relié ces classes à  la classe qui recueille le comptage de tes instances. :)
    Ca n'aurait sans doute pas fait ce qu'il voulait, le retainCount !
    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 ;)
  • Eddy58Eddy58 Membre
    15:45 modifié #19
    Ha bon ? Il y a quelque chose qui m'échappe alors ? ???
    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 ?
  • 15:45 modifié #20
    Un peu bricolage, je trouve.... Si tu crées des pointeurs vers des taches, que tu les alloues alloc/init et que tu ne les releases pas explicitement, tu auras toujours tes trois taches.

    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é.
  • Eddy58Eddy58 Membre
    novembre 2005 modifié #21
    dans 1131975006:

    Un peu bricolage, je trouve.... Si tu crées des pointeurs vers des taches, que tu les alloues alloc/init et que tu ne les releases pas explicitement, tu auras toujours tes trois taches.

    Oui, c'est juste pour le principe et l'exemple, c'est certain qu'il manque les release et d'autres choses. ;)

    dans 1131975006:

    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é.

    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 ?
  • AliGatorAliGator Membre, Modérateur
    15:45 modifié #22
    La question est surtout que :
    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 :
    NSTask* t1;<br />NSTask* t2;<br />NSTask* t3;<br />NSArray* tab;<br />t1 = [[NSTask alloc] init];<br />t2 = [[NSTask alloc] init];<br />t3 = t1;<br />tab = [NSArray arrayWithObjects:t1,t2,nil];
    
    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
  • 15:45 modifié #23
    En tant que programmeur, tu n'es pas responsable de la création et la libération de l'objet. Ta seule responsabilité est de faire que la somme des variations de retaincount soit nulle (soit de faire un nombre de (auto)release correspondant au nombre de retain (+ alloc/copy... si tu crées un objet)).
    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.
  • novembre 2005 modifié #24
    dans 1131979286:

    - 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 ;)


    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).
  • AliGatorAliGator Membre, Modérateur
    15:45 modifié #25
    dans 1131981538:

    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).
    Exact, je le sais en pus j'aurais dû y pens... heu c'était pour voir s'il y en avait qui suivaient et liraient jusqu'au bout  ;)
  • Eddy58Eddy58 Membre
    novembre 2005 modifié #26
    Ha ben voilà  des explications comme je les aime pour me dire quand je me plante ! ;D
    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]
    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].

    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.
  • 15:45 modifié #27
    Ah oui. C'est mieux en effet, mais tu ne crois pas que ([task retainCount] > 0) ne peut être allègrement substitué par (task), puisqu'un objet qui existe a forcément un retainCount > 0?
  • AliGatorAliGator Membre, Modérateur
    15:45 modifié #28
    Mouais.... autant tester s'il est nil, dans ce cas ;)
    unsigned int nb = 0;<br />if (t1) nb++;<br />if (t2) nb++;<br />if (t3) nb++;
    


    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]
  • Eddy58Eddy58 Membre
    novembre 2005 modifié #29
    Oui aprés tout c'est vrai qu'un simple test d'existence de l'instance est au final suffisant.

    -(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.:)
Connectez-vous ou Inscrivez-vous pour répondre.