IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

Réseau C Discussion :

[timer & thread] timeout & socket non bloquant


Sujet :

Réseau C

  1. #1
    Membre régulier
    Profil pro
    Inscrit en
    Février 2007
    Messages
    107
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Février 2007
    Messages : 107
    Points : 82
    Points
    82
    Par défaut [timer & thread] timeout & socket non bloquant
    bonjour
    Un thread lance un timer (qui fonctionne bien). Comment faire simplement opur que la thread soit informé du timeout de ce timer . J'ai pensé à la création d'une pipe entre le deux mais y a t'il plus simple? Petre avec la gestion des signaux (unix)?
    merci

  2. #2
    Membre émérite Avatar de nicolas.sitbon
    Profil pro
    Inscrit en
    Août 2007
    Messages
    2 015
    Détails du profil
    Informations personnelles :
    Âge : 40
    Localisation : France

    Informations forums :
    Inscription : Août 2007
    Messages : 2 015
    Points : 2 280
    Points
    2 280
    Par défaut
    Mets un bout de code au moins s'il te plait car on sait même pas de quelle thread tu parles (main ou fille).
    Cordialement.
    "The quieter you become, the more you are able to hear"
    "Plus vous êtes silencieux, plus vous êtes capable d'entendre"

  3. #3
    Membre régulier
    Profil pro
    Inscrit en
    Février 2007
    Messages
    107
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Février 2007
    Messages : 107
    Points : 82
    Points
    82
    Par défaut
    Voici le programme de la thread. a un moment donné elle lance le timer. Mais comment lui dire que letimeout est franchi
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    Thread  {
    ...
    startimer();
    ...
     
    }
    le prog timer:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    void action() {...}
     
    void starttimer() {
    #ifdef BSD
    signal(SIGALRM, action);
    #else
    struct sigaction act;
    act.sa_handler = action;
    act.sa_flags = SA_RESTART;
    if(sigaction(SIGALRM, &act, NULL) == -1) {
        fprintf(stderr, "error %d in sigaction\n");
    }
    #endif                                                               
    tempo.it_interval.tv_sec = INTERVAL_SEC;                                        
    tempo.it_interval.tv_usec = INTERVAL_MICROSEC;                                  
    tempo.it_value.tv_sec = INTERVAL_SEC;                                           
    tempo.it_value.tv_usec = INTERVAL_MICROSEC;                                     
    setitimer(ITIMER_REAL, &tempo, 0);     
    }

  4. #4
    Expert éminent sénior
    Avatar de Emmanuel Delahaye
    Profil pro
    Retraité
    Inscrit en
    Décembre 2003
    Messages
    14 512
    Détails du profil
    Informations personnelles :
    Âge : 67
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Retraité

    Informations forums :
    Inscription : Décembre 2003
    Messages : 14 512
    Points : 20 985
    Points
    20 985
    Par défaut
    Citation Envoyé par untipy
    Voici le programme de la thread. a un moment donné elle lance le timer. Mais comment lui dire que letimeout est franchi
    <...>
    En général, on utilise select() pour bloquer la boucle du thread. On peut régler un timeout.
    Pas de Wi-Fi à la maison : CPL

  5. #5
    Membre régulier
    Profil pro
    Inscrit en
    Février 2007
    Messages
    107
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Février 2007
    Messages : 107
    Points : 82
    Points
    82
    Par défaut
    ok, mais j'aimerai ne pas bloqué le thread, car le timer peux etre long, et la thread doit faire autre chose a coté.
    en fait je voudrais gérer çà comme une interruption et la ... ail ....!!

  6. #6
    Membre régulier
    Profil pro
    Inscrit en
    Février 2007
    Messages
    107
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Février 2007
    Messages : 107
    Points : 82
    Points
    82
    Par défaut
    dans la fonction action() peux t'on ajouté un lien vers la thread pour lui dire 'timer fini'??

  7. #7
    Expert éminent sénior
    Avatar de Emmanuel Delahaye
    Profil pro
    Retraité
    Inscrit en
    Décembre 2003
    Messages
    14 512
    Détails du profil
    Informations personnelles :
    Âge : 67
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Retraité

    Informations forums :
    Inscription : Décembre 2003
    Messages : 14 512
    Points : 20 985
    Points
    20 985
    Par défaut
    Citation Envoyé par untipy
    ok, mais j'aimerai ne pas bloqué le thread, car le timer peux etre long, et la thread doit faire autre chose a coté.
    en fait je voudrais gérer çà comme une interruption et la ... ail ....!!
    En principe, un thread est bloqué et ne se débloque que sur évènements. Avec select(), les évènements sont (pour simplifier) :

    - échéance du timer()
    - réception sur flux entrant (y compris sockets)
    - émission sur flux sortant (idem)

    Une interruption et un thread sont deux concepts différents. Tu peux néanmoins débloquer un thread cycliquement si tu veux faire une sorte de polling en réglant le timeout de select() sur une valeur courte (tick)... Tu peux alors gérer un timeout long en comptant les ticks... Tout dépend de l'application.

    Nota : un thread qui tourne en permanence (boucle 'blanche') est considéré comme 'asocial"'. Il doit y avoir au moins une suspension (sleep(1)) dans la boucle pour laisser le système respirer, surtout si il est de type 'coopératif' (Linux, par exemple).
    Pas de Wi-Fi à la maison : CPL

  8. #8
    Expert éminent sénior
    Avatar de Emmanuel Delahaye
    Profil pro
    Retraité
    Inscrit en
    Décembre 2003
    Messages
    14 512
    Détails du profil
    Informations personnelles :
    Âge : 67
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Retraité

    Informations forums :
    Inscription : Décembre 2003
    Messages : 14 512
    Points : 20 985
    Points
    20 985
    Par défaut
    Citation Envoyé par untipy
    dans la fonction action() peux t'on ajouté un lien vers la thread pour lui dire 'timer fini'??
    Personnellement, j'utilise un flag du contexte pour signaler la fin à un thread 'fils'. Je crois qu'il y a des exemples dans mon article...

    http://emmanuel-delahaye.developpez.com/pthreads.htm
    Pas de Wi-Fi à la maison : CPL

  9. #9
    Membre régulier
    Profil pro
    Inscrit en
    Février 2007
    Messages
    107
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Février 2007
    Messages : 107
    Points : 82
    Points
    82
    Par défaut
    j'ai inséré un flag dans le prog timer
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    void action() { toto=1;}
    et toto est globale, connu de la thread également
    mais celle-ci ne le voit pas
    prog thread
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    while (1){
    ...
    if (toto ==1){ 
    printf("\nVAL TOTO:%d\n",toto);
    toto=0;
    }
    ...
    }

  10. #10
    Membre régulier
    Profil pro
    Inscrit en
    Février 2007
    Messages
    107
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Février 2007
    Messages : 107
    Points : 82
    Points
    82
    Par défaut
    j'ai trouvé en fait le drapeau fonctionne mais a un moment dans le prgramme thread j'utilise la fonction read et cette fonction est bloquante ...

  11. #11
    Membre émérite Avatar de nicolas.sitbon
    Profil pro
    Inscrit en
    Août 2007
    Messages
    2 015
    Détails du profil
    Informations personnelles :
    Âge : 40
    Localisation : France

    Informations forums :
    Inscription : Août 2007
    Messages : 2 015
    Points : 2 280
    Points
    2 280
    Par défaut
    surtout si il est de type 'coopératif' (Linux, par exemple)
    Linux n'est pas coopératif, il utilise 3 politiques d'ordonnancement : la première pour les processus ordinaire, et les 2 autres pour les processus temps réels.
    La politique appliquée varie selon le type de processus qui peut être soit SCHED_FIFO (temps réel non préemptible), soit SCHED_RR (temps réel préemptible) soit SCHED_OTHER (processus ordinaire préemptible).
    Enfin untipy pourquoi utilises-tu signal() au lieu de sigaction dans le cas d'un bsd?
    "The quieter you become, the more you are able to hear"
    "Plus vous êtes silencieux, plus vous êtes capable d'entendre"

  12. #12
    Membre régulier
    Profil pro
    Inscrit en
    Février 2007
    Messages
    107
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Février 2007
    Messages : 107
    Points : 82
    Points
    82
    Par défaut
    si si j'utilise bien signal()

    mais comment rendre un read() non bloquant, si il n'y a rien on continue l'éxécution du prog

    c'est recv() ???

  13. #13
    Membre émérite Avatar de nicolas.sitbon
    Profil pro
    Inscrit en
    Août 2007
    Messages
    2 015
    Détails du profil
    Informations personnelles :
    Âge : 40
    Localisation : France

    Informations forums :
    Inscription : Août 2007
    Messages : 2 015
    Points : 2 280
    Points
    2 280
    Par défaut
    J'attend toujours que tu postes ton code en entier sinon c'est du bricolage et on risque de perdre plus de temps qu'autre chose.
    Cordialement.
    "The quieter you become, the more you are able to hear"
    "Plus vous êtes silencieux, plus vous êtes capable d'entendre"

  14. #14
    Membre régulier
    Profil pro
    Inscrit en
    Février 2007
    Messages
    107
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Février 2007
    Messages : 107
    Points : 82
    Points
    82
    Par défaut
    oups !!

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    void *thread(void *param)
    int sck = *((int *) param);
    while(1)
    {
    if (toto ==1)
    {
    printf("timeout");
    }
     
    len = recv (sck,msg,sizeof msg - 1,0);
    if(len < 0)
    { ...}
    /*apres c'est du traitement sur msg*/
    }

  15. #15
    Membre régulier
    Profil pro
    Inscrit en
    Février 2007
    Messages
    107
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Février 2007
    Messages : 107
    Points : 82
    Points
    82
    Par défaut
    en fait je suis parti sur çà :
    utilisation d'un timer
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
     fd_set rfds;
                struct timeval tv;
                int retval;
                FD_ZERO(&rfds);
                FD_SET(sck, &rfds); /* on ajoute la socket a regarder */
                tv.tv_sec = 2;
                tv.tv_usec = 0;
                retval = select(0, &rfds, NULL, NULL, &tv);
     
                if (retval)
                {
                    /* infos reçues sur sck dans les 2 secondes*/
                    len = read(sck,msg,4096);
    }
    else{printf"rienr recu");}
    mais il détecte jamais rien en entrée du socket

  16. #16
    Membre régulier
    Profil pro
    Inscrit en
    Février 2007
    Messages
    107
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Février 2007
    Messages : 107
    Points : 82
    Points
    82
    Par défaut
    est-ce qq'un a un exemple de lecture sur socket non bloquant, que je puisse debbugé mon prog svp ?


  17. #17
    Expert éminent sénior
    Avatar de Emmanuel Delahaye
    Profil pro
    Retraité
    Inscrit en
    Décembre 2003
    Messages
    14 512
    Détails du profil
    Informations personnelles :
    Âge : 67
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Retraité

    Informations forums :
    Inscription : Décembre 2003
    Messages : 14 512
    Points : 20 985
    Points
    20 985
    Par défaut
    Citation Envoyé par untipy
    est-ce qq'un a un exemple de lecture sur socket non bloquant, que je puisse debbugé mon prog svp ?
    Pourquoi faire un socket non bloquant .? C'est absurde et contre productif. Si on utilise les threads c'est pour que ça bloque sauf quand traire (réception etc.).

    Refait ta conception en mode bloquant, tu verras que c'est beaucoup plus clair et plus simple. Des traitements en parallèle ? Faire plusieurs threads 'socialement corrects'...
    Pas de Wi-Fi à la maison : CPL

  18. #18
    Membre régulier
    Profil pro
    Inscrit en
    Février 2007
    Messages
    107
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Février 2007
    Messages : 107
    Points : 82
    Points
    82
    Par défaut
    Voila j'ai trouvé mon bug .... oufff
    alors petit retour d'expérience si cela peut être utile a d'autres programmeurs ...

    je suis sur linux
    donc pour faire une socket non bloquant en lecture, il faut configurer la fonction select
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    int select( int nfds,fd_set* readfds,fd_set* writefds,fd_set* exceptfds,const struct timeval* timeout );
    sachant que nfds : [doit valoir le plus grand identifiant de socket, plus 1 (non utilisé sous Windows).
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    int select( socket+1,...)
    Le plus 1 est SUPER important, c'était mon bug. (Le code qui va avec cette explication est page 1 en bas)


    je fais cela car je fait du polling sur plusieurs socket ... y a plus classe ?

  19. #19
    Expert éminent sénior
    Avatar de Emmanuel Delahaye
    Profil pro
    Retraité
    Inscrit en
    Décembre 2003
    Messages
    14 512
    Détails du profil
    Informations personnelles :
    Âge : 67
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Retraité

    Informations forums :
    Inscription : Décembre 2003
    Messages : 14 512
    Points : 20 985
    Points
    20 985
    Par défaut
    Citation Envoyé par untipy
    je suis sur linux
    donc pour faire une socket non bloquant en lecture, il faut configurer la fonction select
    Non, rien à voir.
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    int select( int nfds,fd_set* readfds,fd_set* writefds,fd_set* exceptfds,const struct timeval* timeout );
    sachant que nfds : [doit valoir le plus grand identifiant de socket, plus 1 (non utilisé sous Windows).
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    int select( socket+1,...)
    Le plus 1 est SUPER important, c'était mon bug.


    je fais cela car je fait du polling sur plusieurs socket ... y a plus classe ?
    Bah oui. Tous les sockets sont bloquants (c'est le mode par défaut et ici, ça n'a pas beaucoup d'importance) et select() t'indique lequel s'est réveillé.

    http://emmanuel-delahaye.developpez....aux.htm#select

    En fait, c'est select() qui est bloquant ici et qui fait le tri...
    Pas de Wi-Fi à la maison : CPL

  20. #20
    Expert éminent sénior

    Profil pro
    Inscrit en
    Janvier 2007
    Messages
    10 603
    Détails du profil
    Informations personnelles :
    Âge : 66
    Localisation : France

    Informations forums :
    Inscription : Janvier 2007
    Messages : 10 603
    Points : 17 913
    Points
    17 913
    Billets dans le blog
    2
    Par défaut
    Citation Envoyé par untipy Voir le message
    Voila j'ai trouvé mon bug .... oufff
    alors petit retour d'expérience si cela peut être utile a d'autres programmeurs ...

    je suis sur linux
    donc pour faire une socket non bloquant en lecture, il faut configurer la fonction select
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    int select( int nfds,fd_set* readfds,fd_set* writefds,fd_set* exceptfds,const struct timeval* timeout );
    sachant que nfds : [doit valoir le plus grand identifiant de socket, plus 1 (non utilisé sous Windows).
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    int select( socket+1,...)
    Le plus 1 est SUPER important, c'était mon bug. (Le code qui va avec cette explication est page 1 en bas)


    je fais cela car je fait du polling sur plusieurs socket ... y a plus classe ?
    Comme a dit Emmanuel, dans ton exemple tu n'utilises pas les sockets non bloquants, mais le select.

    Pour un socket non bloquant, il faut le passer en mode asynchrone...du style :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
     
      pid =getpid();
     
       bidon = (int) pid;
    #ifndef LINUX
       retour = ioctl(requete,SIOCSPGRP,&bidon);
    #else
       retour = fcntl(requete,F_SETOWN,(long)bidon);
    #endif
       if ( retour < 0 )
         return retour ;
     
       /*
        *Initialiser l'option asynchrone pour le socket
        */
    #ifndef LINUX
       bidon = 1;
       retour = ioctl(requete,FIOASYNC,&bidon);
    #else
       bidon = O_ASYNC ;
       retour = fcntl(requete,F_SETFL,(long)bidon);
    #endif
    ET PUIS ajouter une routine de réception par signal :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
           signal(SIGIO,fonction);
    Note1 : Attention, dans le code donné ci-dessus, le "else" veut dire un autre système au moins unixoide (en tous cas pas Windows, car les appels ne sont pas les mêmes pour les sockets).

    Note2 : il faut bien entendu inclure ioctl.h ou fnctl.h, plus signal.h, et vraisemblablement vérifier les définitions des signaux (il est possible que les POLL ne soient pas définis, suivant la version du kernel).

    Ensuite, il n'est pas certain que le poll t'indique ce que tu veux. Il faut vérifier par rapport aux file descriptor. Il peut également indiquer une rupture de communication, que ce soit du fait d'un client, du serveur, ou d'un kill ou d'un ctrlC.

    Mais c'est effectivement la philosophie à utiliser pour un serveur à multpile clients (et éventuellement multiples esclaves).
    "Un homme sage ne croit que la moitié de ce qu’il lit. Plus sage encore, il sait laquelle".

    Consultant indépendant.
    Architecture systèmes complexes. Programmation grosses applications critiques. Ergonomie.
    C, Fortran, XWindow/Motif, Java

    Je ne réponds pas aux MP techniques

+ Répondre à la discussion
Cette discussion est résolue.
Page 1 sur 2 12 DernièreDernière

Discussions similaires

  1. Socket non bloquant
    Par Shredder dans le forum Web & réseau
    Réponses: 1
    Dernier message: 29/10/2007, 11h44
  2. socket non bloquant
    Par Mister_Don dans le forum C++
    Réponses: 18
    Dernier message: 17/08/2007, 17h57
  3. [Réseau] socket non bloquant
    Par beLz dans le forum Réseau
    Réponses: 2
    Dernier message: 28/07/2007, 15h20
  4. Réponses: 3
    Dernier message: 20/10/2006, 19h50
  5. socket non bloquante
    Par jeje99 dans le forum Réseau
    Réponses: 15
    Dernier message: 21/02/2006, 08h52

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo