Swisslinux.org

− Le carrefour GNU/Linux en Suisse −

 

Langue

 

Le Forum

Vous n'êtes pas identifié.

  • Index
  •  » Développement
  •  » [C] pipe(), fork(), dup2(), close() et multi-threading (abandon)

#1 23 Dec 2008 20:36:48

[GO]Skywalker13
Modérateur
Lieu: Choëx (VS)
Date d'inscription: 05 Oct 2004
Messages: 896
Site web

[C] pipe(), fork(), dup2(), close() et multi-threading (abandon)

Hello,

j'ai un problème au niveau du multi-threading concernant les fonctions pipe(), fork(), dup2(), et close() qui ne sont (à prioris) pas MT-Safe. A noter que dans la doc de la glibc je ne trouve pas d'informations explicite. Mais du coup ça me pose un problème majeur (dans un cas d'utilisation précis) avec une bibliothèque sur laquelle je bosse.

Je m'explique.. cette bibliothèque utilise abondamment des threads ainsi que des fork(). Il y a un superviseur qui sérialise les fonctions de l'API public pour garantir d'être MT-Safe. Mais, il y a un superviseur par handle et non un seul superviseur global pour tout le monde.

En général on utilise la lib qu'avec un seul handle, donc un seul superviseur et la vie est belle. Rien n'est global donc il est également possible de créer plusieurs handles (donc plusieurs superviseurs). Le tout étant compilé avec -D_REENTRANT la majorité des fonctions sont suffisamment safes. Par contre il se peut, si l'application qui utilise la lib est également multi-threads, qu'il y ait donc deux fork(), pipe(), etc qui se produisent en même temps.
Et la où ça devient encore plus emmerdant, c'est si celui qui utilise la lib va également faire appel à un pipe() (par exemple) dans son prog.

Au début je m'étais dis, pour être MT-Safe, je n'utilise pas directement pipe() et cie, mais je créer des fonctions my_pipe(), etc,.. qui protègerait le vrai pipe() avec un mutex global pour tous les potentiels superviseurs. Mais ça ne règle le problème qu'à moitier. Vu que si celui qui utilise la lib parallélise également un pipe() en même temps que mes my_pipe().. mon mutex n'y changera rien.

Une possibilité serait d'exploiter l'argument -wrap du linker afin de wrapper toutes les fonctions qui posent problème à l'aide d'un

Code:

#include <pthread.h>
#include <unistd.h>

static pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER;

int
__wrap_pipe (int fildes[2])
{
  int res;
  pthread_mutex_lock (&mutex);
  res = __real_pipe (fildes);
  pthread_mutex_unlock (&mutex);
  return res;
}

Mais bon, je pense que vous serez d'accord avec moi que c'est débile.. je ne peux pas demander à l'utilisateur de la lib d'explicitement faire un `-wrap pipe` avec le linker..

Ca devrait être le job de la glibc!

Alors que faire? Il n'existe pas des fonctions équivalentes réentrantes ou mt-safe??


Mathieu SCHROETER
log.schroetersa.ch

Hors ligne

 

#2 23 Dec 2008 22:58:55

[GO]Skywalker13
Modérateur
Lieu: Choëx (VS)
Date d'inscription: 05 Oct 2004
Messages: 896
Site web

Re: [C] pipe(), fork(), dup2(), close() et multi-threading (abandon)

En fait je suis surement un bouffon.. toutes ces fonctions sont Asnyc-Signal Safe (d'après les spécifications UNIX).. je dois avoir un bug ailleurs.. pourtant..
bizarre..


Mathieu SCHROETER
log.schroetersa.ch

Hors ligne

 

#3 25 Dec 2008 10:39:09

[GO]Skywalker13
Modérateur
Lieu: Choëx (VS)
Date d'inscription: 05 Oct 2004
Messages: 896
Site web

Re: [C] pipe(), fork(), dup2(), close() et multi-threading (abandon)

Bon je laisse tomber, de toute façon même si ça marchait correctement ça impliquerait d'autres problèmes plus complexe ailleurs..

Et juste pour la forme et par rapport à mes recherches..
- Il semblerait que fork() endort tous les threads le temps de son exécution et est donc sûre.
- dup2() est atomique et ne peut donc pas bugger mais sans garanti qu'il réussi la duplication.. par contre le plus étrange c'est que je l'utilise uniquement via un sub-process et il échoue qu'en même. Il me retourne un "Bad file descriptor" 1 fois sur 10 dans une utilisations en parallèle.  Je duplique en fait un descripteur dans le STDOUT_FILENO et STDERR_FILENO. Je suppose que le problème se situe à ce niveau là mais quelque chose m'échappe, je ne vois pas pourquoi 2 sub-process qui dupliqueraient dans le stdout/stderr en même temps peuvent échouer.
- pipe() semble ne jamais échouer.
- close() n'intervient pas vraiment dans le problème car ça merde avant son utilisation..


Mathieu SCHROETER
log.schroetersa.ch

Hors ligne

 
  • Index
  •  » Développement
  •  » [C] pipe(), fork(), dup2(), close() et multi-threading (abandon)

Pied de page des forums

Powered by FluxBB