Forum |  HardWare.fr | News | Articles | PC | S'identifier | S'inscrire | Shop Recherche
1514 connectés 

  FORUM HardWare.fr
  Programmation
  C

  [C] POSIX message queues : #define MQ_MAXMSG 10 ???

 


 Mot :   Pseudo :  
 
Bas de page
Auteur Sujet :

[C] POSIX message queues : #define MQ_MAXMSG 10 ???

n°1817208
kaloskagat​os
Posté le 26-11-2008 à 17:32:52  profilanswer
 

Bonjour à tous,
 
J'ai écrit un bout de code dans mon appli en utilisant les messages queues fournies par la lib real time (librt) du système sous linux, je teste le bouzin et ça ne marche pas. Je tâtonne, je cherche un peu sur le net, et finalement je découvre que l'API n'autorise l'utilisation que de 10 messages par queue...
 

Code :
  1. #define MQ_MAXMSG  10


 :o  
 
La structure mq_attr permet de définir mq_maxmsg le nombre de message de la queue, si par malheur on en définit plus de 10 mq_open échoue avec un "invalid argument"...
 
Le #define MQ_MAXMSG n'est documenté nulle part, ce n'est qu'en cherchant sur le net que j'ai trouvé d'autres personnes qui ont rencontré le problème. Le plus étonnant c'est qu'on trouve sur le net d'autres version de la lib qui définissent MQ_MAXMSG à 40, ou à 100. Pourquoi cela n'est-il pas normalisé? Pour ma part mon système possède la librt-2.3.4.so, mais mon appli doit fonctionner sur d'autres machines. Je vais partir sur une autre solution mais j'aurais aimé comprendre cette aberration de fixer un paramètre aussi important dans une lib aussi commune...


---------------
« Le hasard, c’est différent de la chance. Parce que la chance, je n'en ai jamais. »
mood
Publicité
Posté le 26-11-2008 à 17:32:52  profilanswer
 

n°1817464
kaloskagat​os
Posté le 27-11-2008 à 10:22:48  profilanswer
 

up :)


---------------
« Le hasard, c’est différent de la chance. Parce que la chance, je n'en ai jamais. »
n°1817484
Taz
bisounours-codeur
Posté le 27-11-2008 à 10:52:26  profilanswer
 

Attention, ça ne marche que mq_open de changer mq_maxmsg.

n°1817487
Taz
bisounours-codeur
Posté le 27-11-2008 à 10:56:48  profilanswer
 

kaloskagatos a écrit :


Le #define MQ_MAXMSG n'est documenté nulle part, ce n'est qu'en cherchant sur le net que j'ai trouvé d'autres personnes qui ont rencontré le problème. Le plus étonnant c'est qu'on trouve sur le net d'autres version de la lib qui définissent MQ_MAXMSG à 40, ou à 100. Pourquoi cela n'est-il pas normalisé?

Parce que c'est une valeur par défaut sans grande importance ? Si tu veux plus, demande plus.
 
T'as tout dans le man, y compris le sysctl /proc pour avoir une valeur supérieure à 10.

n°1817498
kaloskagat​os
Posté le 27-11-2008 à 11:06:58  profilanswer
 

Taz a écrit :

Attention, ça ne marche que mq_open de changer mq_maxmsg.


 
Je comprends pas la phrase :D mq_open plante avec invalid argument :
 

Code :
  1. struct mq_attr atr;
  2. atr.mq_maxmsg = 11;
  3. atr.mq_msgsize = 1024;
  4. mq_open("/dawa", O_CREAT | O_RDWR , S_IRWXO, &atr);


 
 

Taz a écrit :

Parce que c'est une valeur par défaut sans grande importance ? Si tu veux plus, demande plus.
 
T'as tout dans le man, y compris le sysctl /proc pour avoir une valeur supérieure à 10.


 
 
Ok je check baby


---------------
« Le hasard, c’est différent de la chance. Parce que la chance, je n'en ai jamais. »
n°1817499
kaloskagat​os
Posté le 27-11-2008 à 11:09:57  profilanswer
 

Je sais que t'as raison, laisse moi chercher.

 


Mais en fait ça me fait chier si je dois régler le nombre max de messages depuis le système, en root à tous les coups, c'est pas très user compliant :/ Comment je fais si je veux distribuer mon appli et être sûr que ça plantera pas à l'exécution?

 

Patapay je cherche toujours le sysctl /proc


Message édité par kaloskagatos le 27-11-2008 à 11:12:16

---------------
« Le hasard, c’est différent de la chance. Parce que la chance, je n'en ai jamais. »
n°1817501
Taz
bisounours-codeur
Posté le 27-11-2008 à 11:18:33  profilanswer
 

minable ta non-initialisation de struct ... soit fais un memset, soit fais un simple "attr = { 0, 1, 2, 3 };" pour être sur que tous les membres que tu n'initilises pas sont à 0 plutôt qu'à des valeurs délirantes.
 
Si t'as besoin d'une taille plus grande:
- tu peux la vérifier en lisant /proc ou quand tu crées ta file, tu vois bien si ton open marche avec la valeur que tu demandes ou pas
- quand la file est pleine, ça bloque, à moins que tu mettes un flag pour que ça ne bloque pas, auquel cas, tu peux ressayer plus tard.

n°1817502
kaloskagat​os
Posté le 27-11-2008 à 11:19:49  profilanswer
 

>>T'as tout dans le man, y compris le sysctl /proc pour avoir une valeur supérieure à 10.  
 
ok bon ça j'ai pas trouvé où tu l'avais vu dans le man de mq_
 
 
sysctl on peut le faire depuis le code, mais bon toucher au noyau c'est pas très à propos dans mon appli, je pense que j'avais fait fausse route en utilisant ça.


---------------
« Le hasard, c’est différent de la chance. Parce que la chance, je n'en ai jamais. »
n°1817506
kaloskagat​os
Posté le 27-11-2008 à 11:23:15  profilanswer
 

Taz a écrit :

minable ta non-initialisation de struct ... soit fais un memset, soit fais un simple "attr = { 0, 1, 2, 3 };" pour être sur que tous les membres que tu n'initilises pas sont à 0 plutôt qu'à des valeurs délirantes.

 


 

C'est toi t'es minable [:masklinn]

 
Taz a écrit :

 

Si t'as besoin d'une taille plus grande:
- tu peux la vérifier en lisant /proc ou quand tu crées ta file, tu vois bien si ton open marche avec la valeur que tu demandes ou pas
- quand la file est pleine, ça bloque, à moins que tu mettes un flag pour que ça ne bloque pas, auquel cas, tu peux ressayer plus tard.

 

- Je veux pas vérifier si ma valeur >10 que je demande marche, je veux que ça marche avec 100 messages par file
- HS

 


Mais merci pour ton intervention, j'y vois plus clair, et je me sens un peu plus crétin :jap:


Message édité par kaloskagatos le 27-11-2008 à 11:23:57

---------------
« Le hasard, c’est différent de la chance. Parce que la chance, je n'en ai jamais. »
n°1817510
Taz
bisounours-codeur
Posté le 27-11-2008 à 11:28:48  profilanswer
 

Nan mais je pense que ton erreur, c'est juste un bug de données pas initialisée ...
 
10 ou 100, c'est le même problème, si tu ne gères pas le cas où la file est pleine, ça fera tot ou tard des surprises. C'est dans le manuel, 100 ça ne marchera pas avec les valeurs par défaut système. La taille totale de la file faut pas l'oublier non plus.

mood
Publicité
Posté le 27-11-2008 à 11:28:48  profilanswer
 

n°1817513
kaloskagat​os
Posté le 27-11-2008 à 11:34:43  profilanswer
 

Je vois pas de bug dans mon initialisation :
 

Code :
  1. struct mq_attr {
  2.     long mq_flags;       /* Flags: 0 or O_NONBLOCK */
  3.     long mq_maxmsg;      /* Max. # of messages on queue */
  4.     long mq_msgsize;     /* Max. message size (bytes) */
  5.     long mq_curmsgs;     /* # of messages currently in queue */
  6. };


 
mq_flags ça va changer quelque chose au moment d'envoyer/lire des messages, moi ça plante quand je fais un mq_open avec mq_maxmsg = 11.
 
mq_curmsgs faut pas l'initialiser si je ne m'abuse.
 
Je poste mon de code de test


---------------
« Le hasard, c’est différent de la chance. Parce que la chance, je n'en ai jamais. »
n°1817520
Taz
bisounours-codeur
Posté le 27-11-2008 à 11:40:45  profilanswer
 

Code :
  1. # struct mq_attr atr;
  2. atr.mq_maxmsg = 11;
  3. atr.mq_msgsize = 1024;


 
Et les autres membres, ils valent quoi ? UB.

n°1817522
kaloskagat​os
Posté le 27-11-2008 à 11:41:35  profilanswer
 

avec #define MAXMSG   11 ça plante avec "Ca plante à l'ouverture: Invalid argument"
avec 10 ça passe.
Mon code est beau.

 

gcc -Wall -pedantic -ansi -lrt mqueue.c

 
Code :
  1. #include <mqueue.h>
  2. #include <sys/stat.h>
  3. #include <stdio.h>
  4. #include <string.h>
  5. #define MAXMSG   11 /* Nombre maximal de message dans la file */
  6. #define MSGSIZE 256 /* Taille maximale des messages */
  7. #define QNAME "/dawa" /* nom de la file */
  8. #define NBSEND    10 /* Nombre de messages effectifs */
  9. #define SUPERGRAND 1000000 /* taille de buffer */
  10. /* -------------------------------------------------------------------------- */
  11. /* Creation de la queue */
  12. /* -------------------------------------------------------------------------- */
  13. mqd_t init()
  14. {
  15.    struct mq_attr   mqattr ;
  16.    mqd_t            qid    ;
  17.    /* Parametre de l'ouverture de la file */
  18.    mqattr.mq_flags   = 0;
  19.    mqattr.mq_maxmsg  = MAXMSG ;
  20.    mqattr.mq_msgsize = MSGSIZE ;
  21.    mqattr.mq_curmsgs = 0;
  22.    /* Suppression d'une eventuelle queue */
  23.    if( mq_unlink( QNAME ) == 0 )
  24.       printf( "Warning : La file %s a été supprimée.\n", QNAME ) ;
  25.    /* Creation de la file */
  26.    qid = mq_open( QNAME, O_RDWR | O_CREAT | O_NONBLOCK , S_IRWXO, &mqattr ) ;
  27.    if( qid == (mqd_t) -1 )
  28.       perror( "Ca plante à l'ouverture" ) ;
  29.    return qid ;
  30. }
  31. /* -------------------------------------------------------------------------- */
  32. /* Suppression de la queue */
  33. /* -------------------------------------------------------------------------- */
  34. int close( mqd_t qid )
  35. {
  36.    /* Abandon du descripteur */
  37.    if( mq_close( qid ) )
  38.    {
  39.       perror( "Ca plante à la fermeture, mais c'est pas vrai !" ) ;
  40.       return 1 ;
  41.    }
  42.    /* Suppression effective de la queue */
  43.    if( mq_unlink( QNAME ) )
  44.    {
  45.       perror( "Ca plante à la destruction de la queue" ) ;
  46.       return 1 ;
  47.    }
  48.    return 0 ;
  49. }
  50. /* -------------------------------------------------------------------------- */
  51. /* Envoi */
  52. /* -------------------------------------------------------------------------- */
  53. int send( mqd_t id )
  54. {
  55.    char *msg = "Ceci est un texte toujours plus long que lg" ;
  56.    if( mq_send( id, msg, strlen(msg), 0 ) )
  57.    {
  58.       perror( "Ca plante à l'envoi nondidiou" ) ;
  59.       return 1 ;
  60.    }
  61.    return 0 ;
  62. }
  63. /* -------------------------------------------------------------------------- */
  64. /* Reception */
  65. /* -------------------------------------------------------------------------- */
  66. int receive( mqd_t qid )
  67. {
  68.    char      buffer[SUPERGRAND] ;
  69.    mqd_t     retVal  ;
  70.    /* Reception d'un message */
  71.    retVal = mq_receive( qid, buffer, SUPERGRAND, NULL ) ;
  72.    if( retVal < 1 )
  73.    {
  74.       perror( "Nous avons rencontré un problème sérieux." ) ;
  75.       printf( "ben ouais, on a lu %d octets\n", retVal ) ;
  76.       return 1 ;
  77.    }
  78.    printf( "On a lu %d octets sans problème\n", retVal ) ;
  79.    return 0 ;
  80. }
  81. /* -------------------------------------------------------------------------- */
  82. /* Main ! */
  83. /* -------------------------------------------------------------------------- */
  84. int main( int argc, char **argv )
  85. {
  86.    mqd_t qid ;
  87.    unsigned i ;
  88.    /* Ouverture de la mqueue de m... */
  89.    qid = init() ;
  90.    if( qid == (mqd_t) -1 )
  91.       return 1 ;
  92. printf( "Init Ok. En attente du feu vert go ouais.\n" ) ;
  93. getchar() ;
  94.    /* Envoi effectif */
  95.    for( i=0; i < NBSEND ; ++i )
  96.    {
  97.       if( send( qid ) )
  98.       {
  99.          printf( "La foirage arrive à l'envoi %u\n", i ) ;
  100.          return 1 ;
  101.       }
  102.    }
  103. printf( "Send Ok. En attente du feu vert go ouais.\n" ) ;
  104. getchar() ;
  105.    for( i=0; i < NBSEND ; ++i )
  106.    {
  107.       if( receive( qid ) )
  108.       {
  109.          printf( "La foirage arrive à la récepcheune %u\n", i ) ;
  110.          return 1 ;
  111.       }
  112.    }
  113. printf( "Receive Ok. En attente du feu vert go ouais.\n" ) ;
  114. getchar() ;
  115.    /* Fermeture qui plante ou pas */
  116.    return close( qid ) ;
  117. }


Message édité par kaloskagatos le 27-11-2008 à 11:44:07
n°1817523
Taz
bisounours-codeur
Posté le 27-11-2008 à 11:42:39  profilanswer
 

1) et le flag, il prend quelle valeur ?
2) voir premier message. Il faut augmenter la limite système.

n°1817526
Taz
bisounours-codeur
Posté le 27-11-2008 à 11:44:06  profilanswer
 

'tain t'es chaud de créer ta propre fonction send ... man 2 send

n°1817527
kaloskagat​os
Posté le 27-11-2008 à 11:44:30  profilanswer
 

J'ai tout initialisé mais sans succès


---------------
« Le hasard, c’est différent de la chance. Parce que la chance, je n'en ai jamais. »
n°1817530
Taz
bisounours-codeur
Posté le 27-11-2008 à 11:46:08  profilanswer
 

Et quand je te parlais de taille de file.
 
 
SUPERGRAND 1000000
 
ça fait du bon bourrage de pile par la suite. Etant donné que la taille des messages/files est bien plus petite que ça

n°1817531
kaloskagat​os
Posté le 27-11-2008 à 11:46:26  profilanswer
 

Taz a écrit :

1) et le flag, il prend quelle valeur ?
2) voir premier message. Il faut augmenter la limite système.


 
 
1) on s'en fout du flag, il sert pas à l'ouverture mais à l'envoi
2) c'est bien ce que j'avais compris, je veux pas toucher au système donc c'est DMC.


---------------
« Le hasard, c’est différent de la chance. Parce que la chance, je n'en ai jamais. »
n°1817534
Taz
bisounours-codeur
Posté le 27-11-2008 à 11:47:14  profilanswer
 

Et manie le perror/strerror/errno pour pouvoir qualifier les -1 retournés, sinon tu peux pas savoir pourquoi ça ne marche pas.

n°1817536
kaloskagat​os
Posté le 27-11-2008 à 11:47:54  profilanswer
 

Taz a écrit :

Et quand je te parlais de taille de file.
 
 
SUPERGRAND 1000000
 
ça fait du bon bourrage de pile par la suite. Etant donné que la taille des messages/files est bien plus petite que ça


 
 
On s'en fout aussi, c'était pour mes tests perso, bien évidemment ceci n'est pas le logiciel que je développe professionnellement pour mon employeur.


---------------
« Le hasard, c’est différent de la chance. Parce que la chance, je n'en ai jamais. »
n°1817538
Taz
bisounours-codeur
Posté le 27-11-2008 à 11:49:45  profilanswer
 

1) ok j'avais pas lu. Ca reste pas idiot d'utiliser généralement la syntaxe d'initialisation.
 
Je comprends pas pourquoi tu bloques vraiment sur la taille de la file. Si elle est pleine, bah tu bloques dessus jusqu'à qu'un autre processus la vide.

n°1817539
kaloskagat​os
Posté le 27-11-2008 à 11:50:12  profilanswer
 

Taz a écrit :

'tain t'es chaud de créer ta propre fonction send ... man 2 send


 
je rêve ou tu me parles de socket là? J'ai pas écrit de fonction send, y'a rien dedans.
 

Taz a écrit :

Et manie le perror/strerror/errno pour pouvoir qualifier les -1 retournés, sinon tu peux pas savoir pourquoi ça ne marche pas.


 
Comme je l'ai dit mon code est magnifique :)


---------------
« Le hasard, c’est différent de la chance. Parce que la chance, je n'en ai jamais. »
n°1817541
Taz
bisounours-codeur
Posté le 27-11-2008 à 11:50:58  profilanswer
 

kaloskagatos a écrit :


 
 
On s'en fout aussi, c'était pour mes tests perso, bien évidemment ceci n'est pas le logiciel que je développe professionnellement pour mon employeur.


Bah on s'en fout oui et non, à force de faire des trucs foireux/baclés pour tester, ça devient dur de savoir si ton test marche ou pas.

n°1817543
kaloskagat​os
Posté le 27-11-2008 à 11:51:56  profilanswer
 

Taz a écrit :

1) ok j'avais pas lu. Ca reste pas idiot d'utiliser généralement la syntaxe d'initialisation.
 
Je comprends pas pourquoi tu bloques vraiment sur la taille de la file. Si elle est pleine, bah tu bloques dessus jusqu'à qu'un autre processus la vide.


 
 
Parce que je bosse sur un simulateur temps réel qui n'a pas le temps d'attendre que la file se vide. Donc j'en reviens à la conclusion que cette API n'est pas faite pour moi.


---------------
« Le hasard, c’est différent de la chance. Parce que la chance, je n'en ai jamais. »
n°1817547
Taz
bisounours-codeur
Posté le 27-11-2008 à 11:52:59  profilanswer
 

kaloskagatos a écrit :


 
je rêve ou tu me parles de socket là? J'ai pas écrit de fonction send, y'a rien dedans.
 

(T'as aussi écrit une close. C'est des mauvaises habitudes à ne pas prendre sinon un jour tu le feras vraiment et tu comprendras jamais pourquoi ça marche pas).

n°1817549
Taz
bisounours-codeur
Posté le 27-11-2008 à 11:53:30  profilanswer
 

kaloskagatos a écrit :

 


Parce que je bosse sur un simulateur temps réel qui n'a pas le temps d'attendre que la file se vide. Donc j'en reviens à la conclusion que cette API n'est pas faite pour moi.


Bah t'as le flag d'open et le flag de receives/send qui te permet de ne pas attendre

Message cité 1 fois
Message édité par Taz le 27-11-2008 à 11:53:45
n°1817551
kaloskagat​os
Posté le 27-11-2008 à 11:56:08  profilanswer
 

Taz a écrit :

(T'as aussi écrit une close. C'est des mauvaises habitudes à ne pas prendre sinon un jour tu le feras vraiment et tu comprendras jamais pourquoi ça marche pas).


 
J'ai pas compris, qu'est-ce que j'ai fait ?  
 
 

Taz a écrit :


Bah t'as le flag d'open et le flag de receives/send qui te permet de ne pas attendre


 
Oui mais ne pas attendre signifie que le send échoue et qu'il faut revenir poster les messages qui ne sont pas passés, moi j'aimerais poster tous mes messages pis continuer à faire autre chose quoi.


---------------
« Le hasard, c’est différent de la chance. Parce que la chance, je n'en ai jamais. »
n°1817567
Taz
bisounours-codeur
Posté le 27-11-2008 à 12:09:02  profilanswer
 

Je comprends, mais si tu penses comme ça, tu vas avoir le problème tous les appels systèmes et fonctions qui se sont pas async (à commencer par le moindre read ou write).
 
Soit tu gères dans une boucle le fait que la file soit pleine, soit tu le traites dans un autre thread ou dans un sous-programme chargé de poster.
 
C'est sans fin comme problème.
 
Empiler encore et encore côté envoyeur, ça ne résout pas forcément ton problème puisque y a forcément une limite à un moment et c'est un peu inquiétant que ça ne vide pas au bon rythme en face ?
 
 
C'est du producteur/consommateur de base en IPC: mq, pipe ou autre le système est pas là pour stocker tous tes messages. Il te donne de tuyaux de taille fixe, si tu veux bufferiser plus, il faut que tu le fasses toi même côté utilisateur.

n°1817583
kaloskagat​os
Posté le 27-11-2008 à 12:22:46  profilanswer
 

J'ai compris ce que tu m'expliques, mais dans mon cas le nombre de messages envoyés a une limite max, c'est dans la spec.  
 
De plus je ne suis pas rentré dans le détail dans mon post mais pour le moment je n'ai qu'un seul processus, l'envoi se fait à t0 et la réception se fait à t1 dans un callback appelé par un échéancier. En bref je me suis fourvoyé avec cette lib, je vais utiliser un buffer circulaire et pis ça ira tout seul.


---------------
« Le hasard, c’est différent de la chance. Parce que la chance, je n'en ai jamais. »
n°1817589
Taz
bisounours-codeur
Posté le 27-11-2008 à 12:30:23  profilanswer
 

Ca c'est sur que si c'est pas threadé ni multiprocessé, c'est pas bien la peine de sortir faire de l'IPC. Si ça se trouve, t'as peut-être meme pas besoin de synchronisation.
 
Comme tu dis, un pauvre buffer, de la synchro comme il faut, et ça doit se faire tout seul. Réfléchi bien à la synchro si c'est 2 thread qui communiquent pour faire quelque chose d'intelligent

n°1817595
kaloskagat​os
Posté le 27-11-2008 à 12:40:19  profilanswer
 

Bein c'est parce que potentiellement un jour ce sera multithreadé que j'ai utilisé ça, donc je voulais déjà le valider.
 
Bon bein thx


---------------
« Le hasard, c’est différent de la chance. Parce que la chance, je n'en ai jamais. »
n°1817599
Taz
bisounours-codeur
Posté le 27-11-2008 à 12:45:07  profilanswer
 

kaloskagatos a écrit :

Bein c'est parce que potentiellement un jour ce sera multithreadé que j'ai utilisé ça, donc je voulais déjà le valider.
 
Bon bein thx


c'est pour de la comme entre processus ça.

n°1817751
kaloskagat​os
Posté le 27-11-2008 à 15:11:52  profilanswer
 

c'est ce que je voulais dire


---------------
« Le hasard, c’est différent de la chance. Parce que la chance, je n'en ai jamais. »
n°1818228
kaloskagat​os
Posté le 28-11-2008 à 10:33:36  profilanswer
 

Taz a écrit :

Code :
  1. # struct mq_attr atr;
  2. atr.mq_maxmsg = 11;
  3. atr.mq_msgsize = 1024;


 
Et les autres membres, ils valent quoi ? UB.


 
 
Au fait ça veut dire quoi UB? Tu m'as insulté?  :fou:


---------------
« Le hasard, c’est différent de la chance. Parce que la chance, je n'en ai jamais. »
n°1818230
babarpapa
Posté le 28-11-2008 à 10:35:04  profilanswer
 

Tu te fous de la gueule de mon pote?

n°1818268
Taz
bisounours-codeur
Posté le 28-11-2008 à 11:05:43  profilanswer
 

babarpapa a écrit :

Tu te fous de la gueule de mon pote?


suce moi papa!

mood
Publicité
Posté le   profilanswer
 


Aller à :
Ajouter une réponse
  FORUM HardWare.fr
  Programmation
  C

  [C] POSIX message queues : #define MQ_MAXMSG 10 ???

 

Sujets relatifs
Préprocesseur C[C] J'essaye de me faire une petite bibliothèques de fonction avec SDL
tri fusion en CListing des différences avec le C++
[C] Problème de lecture dans un fichier en C : fscanf[C] Bataille navale, sauvegarde/restauration.
[C] Comment faire un getchar() sans pause après [débutant][questionalacon] scanf et chaîne de caractères
[C] Opérations avec des matrices[Résolu] Problème pour lire et écrire des fichiers pgm en C++
Plus de sujets relatifs à : [C] POSIX message queues : #define MQ_MAXMSG 10 ???


Copyright © 1997-2022 Hardware.fr SARL (Signaler un contenu illicite / Données personnelles) / Groupe LDLC / Shop HFR