C++ "NULL streambuffer" létrehozása

 ( dandor | 2008. szeptember 16., kedd - 10:24 )

Sziasztok!

A következő C++-os problémát szeretném megoldani.
Adott egy C++ program, amit Windows-on és OnTime realtime operációs rendszeren futtatok.
A problémám a következő. Szeretném a szöveges logokat cout stílusban a c++ standard lib ostream osztályával előállítani. Alapvetően 4 féle működése lenne a logolásnak. osstream, ofstream, cout és tervezek egy null_stream-et. Ez utóbbi egy sima ostream példány lenne és a beleírt karaktereket egyszerűen "eldobná" nem történne tényleges logolas (hogy szükség esetén csökkentsem a rendszer terhelését). Ezt a null stream-et egy olyan ostream-el valósítanám meg amit egy "null streambuffer"-el inicializalnek az ostream konstruktoraban. A kérdésem az volna, hogy hogyan valósíthatnám meg ezt a null streambuffert. Az eredeti streambuf osztály mely tagfuggvényeit override-oljam és azok hogyan működjenek? Ha valaki foglalkozott már hasonló dologgal, örömmel venném a tanácsait.

Előre is köszi a segítséget!

Hozzászólás megjelenítési lehetőségek

A választott hozzászólás megjelenítési mód a „Beállítás” gombbal rögzíthető.

Szerintem ez segíthet:
http://spec.winprog.org/streams/

"...handing C++ to the average programmer seems roughly comparable to handing a loaded .45 to a chimpanzee."
-- Ted Ts'o

Köszönöm a választ, megnézem a linket.

Lehet, hogy offtopic, de ha tényleg csökkenteni akarod a trace-ből adódó többletterhelést akkor érdemes úgy megírni a programot, hogy kikapcsolt debug esetén egyáltalán ne fussanak le a trace sorok.

E helyett:
myLog<<"Az x változó értéke: " << x;

Ezt:
if(myLogOn) myLog<<"Az x változó értéke: " << x;

Így átírva rengeteg függvényhívást megspórolsz, amik melléhatás nélkül és láthatatlanul, de lefutnak egyébként - még null stream esetén is.

Szóval tényleg nem beledumálni akartam, csak ez egy régi trükk és én is nemrég szembesültem a fontosságával.

Szerintem akkor mar inkabb makro:

#ifdef VALAMI
cout << "boo" << endl;
#endif

Elonye, hogy meg a feltetel vizsgalat sem kell.


"If you must mount the gallows, give a jest to the crowd, a coin to the hangman, and make the drop with a smile on your lips" The Wheel of Time series

A preprocesszoros megoldást jelenleg is használom a kritikus helyeken, viszont bizonyos körülmények között inkább a memóriafoglalással van gondom egy pl egy stringbuffer alapú megoldásnál, nem pedig a cpu terheléssel. (A fileba írás a realtime követelmények miatt általában nem járható)
Ezért lenne megfelelőbb, ha egyes esetekben be tudnék állítani egy null stream-et, pl amikor egyéb módon is meg tudok győződni a működés helyességéről. Ilyenkor nem szívesen "szemetelném" tele preprocesszor direktívákkal a kódot.

Nem kell a preprocesszor direktívákat mindenhová beleírnod a kódba, írhatsz makrót, amit csak a header állományban választasz ketté preprocesszor direktívával.

Ha ügyesen írod meg a memória foglalást is megspórolod. Fordítási idejű kikapcsolással mindenképp, de ha ügyesen írod meg akár runtime kikapcsolhatóság mellett is.

Szóval a példakódok nyilván csak iránymutatók, nem kell szó szerint érteni.

Log fájlba írását real time követelmények mellett a lognak egy ringbufferbe (http://en.wikipedia.org/wiki/Circular_buffer) írás közbeiktatásával és másik szálból fájlba írással lehet a legjobban megoldani. Így a kecske is jóllakik (nincs sok és kiszámíthatatlan latency-je a loggolásnak) és a káposzta is megmarad (van elemezhető logod a real-time kódról is). Csak a ringbuffer méretét és a fájlba író szál időzítését kell jól megválasztani.

Köszi a választ. Ez a ring bufferes ötlet még jó szolgálatot fog tenni, mert várhatóan lesznek hosszabb futtatások is, amiket muszaj lesz diszkre logolni lehetőleg egyenletes sebességgel.

+1

szép napokat
zsömi

hahahahaha :D

hat igen, latjatok, a proxy classok a java reflectionben odabasznak.

Nalunk a cegnel az tobb tipusu traceflag letezik es mindegyik kulonbozo tracelevel-en futhat. Ja es a program futasa kozben barmikor valtozhatnak a trace beallitasok. Egy 16 byte-os bytestream irja le, hogy melyik modul milyen tracelevel-en fut.

pl: tarce_flags = "4500012000000000"
ahol, TCPIP level=4, DB level=5, Event=0, stb

amikor pl tracelni akarom a socket() felhivast es azt szeretnem hogy abban az esetben jelenjen meg a tracefile-ban, ha TCPIP level legalabb 4, akkor a kovetkezot csinalom:

[code]
TTIP4 trc( "socket -->\n");
rslt = socket (...);
TTIP4 trc( "socket <-- (rslt=%d)\n", rslt);

,ahol
#define TTIP1 if ( pcx->trace_flags[0] >= '1')
#define TTIP2 if ( pcx->trace_flags[0] >= '2')
#define TTIP3 if ( pcx->trace_flags[0] >= '3')
#define TTIP4 if ( pcx->trace_flags[0] >= '4')
.
.
#define TTDB1 if ( pcx->trace_flags[1] >= '1')
.
.

igy lehetoseg van futasi idoben, kulonbozo szempontok szerint ki-be kapcsolgatni a modulok trace szintjet. nincs felesleges fuggvenyhivas, csak egy bytecompare, nem tul nagy overhead.

ez nekem bejott, nem zavaro nagyon a trace a kodban. marmint en megszoktam.

udv,
hofi75

Köszi a választ. Ezekkel a TTIPx jellegű define okkal tenyleg eléggé tömören leírható a feltétel.

a kod attol meg nagyon NAGYON ronda lesz.

Ez nem kodszepsegverseny, az ket ablakkal arrebb.
--

()=() Ki oda vagyik,
('Y') hol szall a galamb
C . C elszalasztja a
()_() kincset itt alant.

ez a NAGYON ronda kod a minimalis licensz eseten 20k Euro, de mar x>1M Euro-ert ( 80.000Mips, 7db mainframe sysplex) is elkelt parszor. Egy olyan szamitokozpontban, ahol 40-50k job/nap vezerleset kell elvegezni, ott fontosabb a stabilitas, mint a kodszepseg. Persze a ketto nem zarja ki egymast, nekem mar eleg jol raallt a szemem.
A kodszepseg nem ezekben a megoldasokban, hanem az algoritmizalas minosegeben keresendo.

Ettol azert meg lehet kuzdeni a kod szepsegeert - mint ahogy a post szepsegeert is. Illik am a code tag zarojat is beilleszteni...
--

()=() Ki oda vagyik,
('Y') hol szall a galamb
C . C elszalasztja a
()_() kincset itt alant.

nekem a compiler dob egy hibat, ha nyitott block-ot hagyok a kodban.
"Te, ezen mar megint nincs sapka!" jut eszembe a ilyen postokrol.

a BBCode-ról volt szó...

akkor egy dologrol beszelunk.

(Oké, de akkor nem compiler.)

Akkor most valamiert nem dobott :D

Felre ne erts, nem azert mondtam, csak finoman probaltam utalni ra, hogy a BBCode-ra illik odafigyelni, mert itt nincs hibakat dobo compiler ;)
--

()=() Ki oda vagyik,
('Y') hol szall a galamb
C . C elszalasztja a
()_() kincset itt alant.

#include <iostream>

class NullBuf : public std::streambuf
{
public:
  int_type overflow(int_type) {}
};

void
func(std::ostream& stream)
{
  stream << "hello world" << std::endl; 
}

int
main()
{
  NullBuf       buf;
  std::ostream  s(&buf);
  func(s);
  //func(std::cout);
}