Afficher un message
Vieux 07/04/2008, 14h08   #2
James Kanze
Aucun Avatar
 
Messages: n/a
Hébergeur:
Par défaut Re: Des streambufs et des pointeurs *pptr()

On Apr 7, 12:10 pm, Luc Hermitte <luc.hermi...@gmail.com> wrote:

> Dans le cadre de la réalisation d'un ostream de log qui sera
> utilisé dans un contexte multithread, je me suis défini un
> streambuf qui mémorise dans des vecteurs (dans des TSS/TLS) ce
> qui circule dans chaque thread.


> Jusque là, tout va bien. Les articles de James m'ayant bien
> mis sur la voie.


> Et puis par curiosité, je suis allé voir ce qui se faisait
> ailleurs. Sur codesearch de google, je suis tombé sur un code
> répondant à la même question. Dans les différences notables,
> il y en a une qui m'a intriguée : la mise à jour des pointeurs
> de la /put area/ avec setp(), pbump(), etc.


> Du coup, je me suis posé la question "mais est-ce bien
> nécessaire" ? Si je ne m'abuse, ces pointeurs servent à tout
> ce qui est seekp/tellp. Ce qui fait que dans mon contexte de
> logs (qui en plus se conclut par un appel à une fonction
> variadique d'ACE), je n'en vois pas trop l'intérêt. D'autant
> que je trouverait bizarre d'obtenir des valeurs différentes
> suivant le thread qui utilise ces fonctions.


Si tu veux des sorties bufferisées, il faut gerer les pointeurs.
Sinon, ce n'est pas la peine.

Ce que j'ai trouvé utile dans un log, c'est d'effectivement
collecter tout un enrégistrement dans un std::vector<> (par
exemple), puis de l'écrire d'un coup. (Sous Unix, l'écriture est
garantie atomique, au moins jusqu'une certaine taille, et avec
les bons paramètres en ouverture, elle est aussi garantie à la
fin de fichier.) Dans ce cas-là, le plus simple, c'est de
simplement faire un push_back() à chaque appel d'overflow(). On
pourrait bien cependant préférer l'utilisation du vector comme
un buffer ; dans ce cas-là, on l'agrandit dans overflow(), et on
met les pointeurs. Quelque chose du genre :

int
LogStreambuf:verflow(
int ch )
{
size_t current = myBuffer.size() ;
myBuffer.push_back( ch ) ;
myBuffer.resize( myBuffer.capacity() ) ;
setp( &myBuffer[ 0 ] + current,
&myBuffer[ 0 ] + myBuffer.size() ) ;
return ch ;
}

(J'ai negligé le cas où ch vaut EOF, pour simplifier.)

Ça reduit les appels virtuels, etc.

Aussi, il peut être intéressant d'avoir un streambuf par thread,
afin de ne pas avoir besoin des locks, ou au moins limiter le
temps qu'on les tient.

--
James Kanze (GABI Software) email:james.kanze@gmail.com
Conseils en informatique orientée objet/
Beratung in objektorientierter Datenverarbeitung
9 place Sémard, 78210 St.-Cyr-l'École, France, +33 (0)1 30 23 00 34
  Réponse avec citation
 
Page generated in 0,06471 seconds with 9 queries