Passer un tableau 2D vers un thread

Passer un tableau 2D vers un thread - C - Programmation

Marsh Posté le 11-12-2008 à 19:12:37    

Bonjour,
 
J'aimerais passer comme argument un tableau 2D vers un thread. Le problème c'est que quoi que je fasse, ce n'est jamais le bon type de pointeur. Voici la méthode que j'utilise pour l'instant et qui me pose des problèmes:
 
Dans main.c:
 

Code :
  1. char tableau[2][20];
  2. pthread_t p_thread;
  3. pthread_create(p_thread,NULL,routine,(void **) tableau);


 
Dans routine.c:
 

Code :
  1. void *routine(void** p_tableau){
  2. char** tableau = p_tableau;
  3. }


 
est-ce que quelqu'un pourrait m'aider ?
 
Merci beaucoup,
oliparcol

Message cité 1 fois
Message édité par oliparcol le 11-12-2008 à 19:13:58
Reply

Marsh Posté le 11-12-2008 à 19:12:37   

Reply

Marsh Posté le 11-12-2008 à 20:31:30    

il convient de passer au fonctions pthread un pointeur de structure contenant tes données. La c'est un peu moche.
 
En outre char[][] != void**

Reply

Marsh Posté le 12-12-2008 à 07:16:55    

comme ça, ça marche aussi, à condition de caster comme il faut au retour et pas en char**.
 
l'argument à routine est un void* et pas un void**. Et tu le castes en "int (*)[10]" et voilà. T'as un pointeur vers la première rangée de ton tableau.

Reply

Marsh Posté le 13-12-2008 à 21:22:33    

oliparcol a écrit :

est-ce que quelqu'un pourrait m'aider ?
 
Merci beaucoup,
oliparcol


 
Je déconseille fortement de passer comme argument à des threads des tableaux qui sont alloués sur la pile d'un autre thread. A moins d'avoir un amour inconditionnel pour le démellage de plats de nouilles trop cuites, ou les bugs quantiques.


---------------
Petit guide Kerberos pour l'administrateur pressé
Reply

Marsh Posté le 15-12-2008 à 11:01:03    

Gf4x3443 a écrit :


 
Je déconseille fortement de passer comme argument à des threads des tableaux qui sont alloués sur la pile d'un autre thread. A moins d'avoir un amour inconditionnel pour le démellage de plats de nouilles trop cuites, ou les bugs quantiques.


ok mais dans ce cas, quelle serait la solution la plus intelligente ? il faut aussi savoir qu'il n'y a qu'un thread qui écrit dans le tableau, les autres ne font que le lire. Et de plus le tableau est déclaré dans le main.

Message cité 1 fois
Message édité par oliparcol le 15-12-2008 à 11:05:42
Reply

Marsh Posté le 15-12-2008 à 13:18:28    

oliparcol a écrit :


il faut aussi savoir qu'il n'y a qu'un thread qui écrit dans le tableau, les autres ne font que le lire

 

C'est pas une raison. Les accès concurrentiels n'ont rien à voir avec ce problème.

 
Citation :

Et de plus le tableau est déclaré dans le main.

 

C'est pas une raison non plus: utiliser des adresses de stack comme moyen d'échange pour des données, c'est la porte ouverte à toute sorte de conneries. A moins de savoir, encore une fois, ce que tu fais.

 
Citation :

ok mais dans ce cas, quelle serait la solution la plus intelligente ?

 

- Le déclarer static (ou comme variable globale) pour qu'il soit dans la zone data.
- L'allouer avec un malloc() pour qu'il soit dans le tas.

 

Les allocations sur la pile, ca ne sert qu'a une chose: avoir des variables auto pour lesquelles on a pas à s'embêter la tête avec le stockage, mais il est _temporaire_ : quand tu vas créer ton thread, le thread créé doit recopier les données, et non pas garder un pointeur dessus.

 

La solution typique: le thread créateur, juste après le pthread_create(3), attend sur une condvar qui sera mise à 1 quand le thread créé aura fini de copier les valeurs. Cette condvar peut être évidemment sur la pile, vu que celle-ci n'aura pas encore été nettoyée par le retour de fonction.

 

Amha, si tu veux faire des pthreads proprement, je te recommande chaudement de lire le bouquin de Butenhof.


Message édité par Gf4x3443 le 15-12-2008 à 13:19:21

---------------
Petit guide Kerberos pour l'administrateur pressé
Reply

Marsh Posté le 15-12-2008 à 16:55:14    

Si le thread est créé puis joiné dans la même fonction, je ne vois pas trop le problème.

Reply

Marsh Posté le 15-12-2008 à 17:24:06    

Ca revient strictement au même qu'utiliser une condvar, vu que l'implémentation de pthread_join(3) dans la libpthread se fait au travers de ce mécanisme.

 

Edit: à ceci près que tu auras un thread qui va bloquer tout le temps de l'execution de l'autre thread, tout cela pour éviter une stack race. C'est overkill, il pourrait faire autre chose voire même libérer les ressources qu'il utilise avec pthread_exit.

 

Edit2: bien évidemment, à condition que la zone utilisée ne soit pas en pile. C'est bien pour ca que Butenhof classe la chose dans "bad design rules".

Message cité 1 fois
Message édité par Gf4x3443 le 15-12-2008 à 17:29:40

---------------
Petit guide Kerberos pour l'administrateur pressé
Reply

Marsh Posté le 15-12-2008 à 22:00:26    

ok super pour l'aide, je vais probablement utiliser une variable globale, c'est ce qui me semble le plus simple

Reply

Marsh Posté le 16-12-2008 à 09:28:54    

Gf4x3443 a écrit :

Ca revient strictement au même qu'utiliser une condvar, vu que l'implémentation de pthread_join(3) dans la libpthread se fait au travers de ce mécanisme.
 
Edit: à ceci près que tu auras un thread qui va bloquer tout le temps de l'execution de l'autre thread, tout cela pour éviter une stack race. C'est overkill, il pourrait faire autre chose voire même libérer les ressources qu'il utilise avec pthread_exit.


Je ne parle pas d'ajouter un pthread_join() simplement pour éviter le faire disparaitre la resource trop tôt. Je dis que si le design fait, pour raison indépendante, qu'on fait un join() dans la même fonction (comme ça semble être le cas dans son exemple), alors je ne vois aucune raison pour ne pas utiliser une zone dans la pile.
 
Les règles générales, c'est bien dans le cas général, mais la pluspart des cas sont des cas particuliers.

Reply

Marsh Posté le 16-12-2008 à 09:28:54   

Reply

Marsh Posté le 16-12-2008 à 13:10:11    

matafan a écrit :

Je dis que si le design fait, pour raison indépendante, qu'on fait un join() dans la même fonction (comme ça semble être le cas dans son exemple), alors je ne vois aucune raison pour ne pas utiliser une zone dans la pile.


 
Je ne vois nulle part de pthread_join() dans l'exemple, donc il te semble mal.
 

Citation :

Les règles générales, c'est bien dans le cas général, mais la pluspart des cas sont des cas particuliers.


 
C'est pas une règle générale, c'est une manière de coder proprement. Chapitre 8 du Butenhof, bonne lecture.


---------------
Petit guide Kerberos pour l'administrateur pressé
Reply

Sujets relatifs:

Leave a Replay

Make sure you enter the(*)required information where indicate.HTML code is not allowed