File írás hiba

Fórumok

File írás hiba

Hozzászólások

Ha jól értem a szitut, van két párhuzamosan futó szálad, az egyik ír egy listába, a másik meg olvas/töröl belőle. Ez tipikusan az a helyzet, amikor a műveleteket mutex-el kell védeni, hogy a listaműveleteid együtt fussanak le, és ne keveredjenek a két szál utasításai.

A szitu a következő:
3 szálam van. 2 olvas 1-1 mikrofonportot (most már sorba ;)), a 3 pedig kiírja file-ba.
Írnál erről a mutexről? Nem igazán tudom, hogy ez mit csinál

Lehet, hogy makacs vagyok, de én még mindig a file-t hibáztatom a felesleges memória miatt

Sziasztok!

Sikerült végre detektálni a hibát, és kijavítani. (2 napja jöttem rá a megoldásra, és csak azért nem írtam ide, mert a gépem "service"-re szorult. No nem azért mert csúnyán elbántam vele, csak a hálókártyám elszállt :) )
Szóval a tényleges hibát nem a file írás okozta, hanem az azt mefghívó thread szál. Igaz, hogy a file műveletek folyamatosan növelték a memória telítetségét, de NEM az én szoftverem memóriáját nyomták meg, csak az oprendszerét. Ami az enyémet nyomta meg, az a folyamatosan meghívott szál volt :( És a file műveletek eléggé megtévesztettek. (A példaprogram memóriaellenörzésénél pedig valóban jól elnéztem az alaprajzot :oops: )

Szóval ez nem kóser:
[code:1:f920eb12e0]pthread_create(&szalazon, NULL, szal_fgv, (void *) arg)[/code:1:f920eb12e0]
Mégpedig azért nem jó, mert így nem szabadul fel a szál, miután befejeződik.
A helyes kódrészlet valahogy így néz ki:
[code:1:f920eb12e0]
pthread_attr_t attr;
pthread_attr_init(&attr);
pthread_attr_setdetachstate( attr, PTHREAD_CREATE_DETACHED);
pthread_create(&szalazon, &attr, szal_fgv, (void *) arg);
[/code:1:f920eb12e0]
Az attribútum beállításával a szál befejezéskor azonnal felszabadul, így ha egymás után többször is elindítjuk és leállítjuk a szálat, nem okoz felesleges memória töbletet. Egyetlen hátránya van csupán: Nem lehet a szálra várakozni (pthread_join), de én mondjuk ezt nem is akartam :)

A segítséget nagyon szépen köszönöm:
GSimonnak,
Popacseknek,
Andrash-nak,
Norcrys-nek,
Bocs-nak.

Sokat tanultam tőletek az elmúlt napok során, és remélem, hogy másnak is sokat fog segíteni ez a topic.

Üdvözlettel:
Stage 81

andrash a király! Valóban ez lehet a gond. A lista nem védett a konkurrens írás ellen. Neked kell mutexet használni.

Létrehozás:
pthread_mutex_t mutex;
pthread_mutex_init(&mutex, NULL);

mind a mikrofon olvasó, mind a file-író threadekben lista használat előtt:
pthread_mutex_lock(&mutex);

lista használat után:
pthread_mutex_unlock(&mutex);

program befejezésekor:
pthread_mutex_destroy(&mutex);

Vagy vmi ilyesmi ...

Ok. Találtam egy qmutex osztályt, nemsokára jelentkezem... Addig is kösszencs

Sziasztok!

Még mindig nem jutottam egyről a kettőre, viszont találtam valamit, ami "felkeltette" az érdeklődésemet. Sajnos csak "morzsák"-at találtam erről is :(
Tud valaki valami konkrétat írni a fájlleíró nélküli fájlkezelésről? A segítséget előre is köszönöm!

Üdv.: Stage 81

Ez fajin :-) Így tényleg nem ugrik meg a memória használatom, igaz a file-ba sem kerül semmi :)
A következő képpen néz ki a példaprogim:
[code:1:53d45c9e0c]
class rogzito{
public:
FILE * mikrofon1, *mikrofon2; // Az egyszerűség kedvéért a mikrofon portokat csak így jelölöm
FILE * f; // A keletkező állomány
pthread_t sz1, sz2, sz3;
pthread_mutex_t m1, m2;
QPtrQueue <int>sor1;
QPtrQueue <int>sor2;
bool mehet;

void szalakIndit();
};

void * MOlvas1(void * arg){
rogzito * r = (rogzito *) arg;
int * adat;
while(r->mehet){
adat = new int; // Bocsi, de ezzel nem tudok mit csinálni
if((fread(adat, sizeof(int), 1, r->mikrofon1))==sizeof(int)){
pthread_mutex_lock(&r->m1);
sor1->enqueue(adat);
pthread_mutex_unlock(&r->m1);
}
}
}

void * MOlvas2(void * arg){
rogzito * r = (rogzito *) arg;
int * adat;
while(r->mehet){
adat = new int; // Bocsi, de ezzel nem tudok mit csinálni
if((fread(adat, sizeof(int), 1, r->mikrofon2))==sizeof(int)){
pthread_mutex_lock(&r->m2);
sor2->enqueue(adat);
pthread_mutex_unlock(&r->m2);
}
}
}

void * Ir(void * arg){
rogzito * r = (rogzito *) arg;
int adat;
if((r->f=fopen("hello.bin", "wb"))==NULL){
printf("File nyitási hiba!\n");
exit(-1);
}
while(r->mehet){
pthread_mutex_lock(&r->m1);
pthread_mutex_lock(&r->m2);
while(r->sor1.count()>0 && r->sor2.count()>0){
adat=* (int *) r->sor1.head();
delete r->sor1.head();
r->sor1.remove();

adat+=* (int *) r->sor2.head();
delete r->sor2.head();
r->sor2.remove();
fwrite(&adat, sizeof(int), 1, r->f);
}
pthread_mutex_unlock(&r->m1);
pthread_mutex_unlock(&r->m2);
}
fclose(f);
pthread_mutex_destroy(&r->m1);
pthread_mutex_destroy(&r->m2);
}

void rogzito::szalakIndit(){
mehet=true;
pthread_mutex_init(&m1, NULL);
pthread_mutex_init(&m2, NULL);
pthread_create(&sz1, NULL, Ir, this);
pthread_create(&sz2, NULL, MOlvas1, this);
pthread_create(&sz3, NULL, MOlvas2, this);
}
[/code:1:53d45c9e0c]

Természetesen a teljesség és pontosság igénye nélkül...
Ha jól értem, akkor a mutex a lock és unlock között lefoglalt memóriaterületet védi. Ha tévednék, akkor légyszi helyesbítsetek!

A mutexeket érdemes a lehetséges legkisebb ideig lock-olva tartani.
Ne a while ciklus elé és után tedd, hanem közvetlenül a queue-használat köré!
Esetleg érdemes kipróbálni a mutex helyett a spinlock-ot, az is hasonló a mutex-hez, csak ha jól tudom gyorsabb annál. A hívások a mutexéhez hasonlóak, csak spin-el heylettesítsd a mutex-et, pl. pthread_mutex_init --> pthread_spin_init.

[quote:73bc6894b8="stage81"]
Ha jól értem, akkor a mutex a lock és unlock között lefoglalt memóriaterületet védi. Ha tévednék, akkor légyszi helyesbítsetek!

Nem. Ha a mutex-et sikeresen lock-olja egy thread, akkor a másik thread nem tudja lock-olni, hanem a lock hívás várakozik egészen addig, mígnem a lock-oló thread unlock-ja a mutex-et.

http://www.yolinux.com/TUTORIALS/LinuxTutorialPosixThreads.html

Átpakolgattam az Ir fuggvenyemben a mutex.lock és unlock -okat. Így a file-ba ugyan úgy nem kerül semmi, és még a memória is elkezdett felfelé kúszni.
[code:1:d02188cee8]
...
while(r->mehet){
while(r->sor1.count()>0 && r->sor2.count()>0){
pthread_mutex_lock(&r->m1);
adat=* (int *) r->sor1.head();
delete r->sor1.head();
r->sor1.remove();
pthread_mutex_unlock(&r->m1);

pthread_mutex_lock(&r->m2);
adat+=* (int *) r->sor2.head();
delete r->sor2.head();
r->sor2.remove();
pthread_mutex_unlock(&r->m2);
fwrite(&adat, sizeof(int), 1, r->f);
}
}
...
[/code:1:d02188cee8]

Mindjárt átcserélem spinre, és azzal is megnézem.

Nem. Ha a mutex-et sikeresen lock-olja egy thread, akkor a másik thread nem tudja lock-olni, hanem a lock hívás várakozik egészen addig, mígnem a lock-oló thread unlock-ja a mutex-et.

Így már értem ;)

Azaz mégis csak "félig-meddig" jó. Fájlba azért nem írt, mert véletlenül elírtam egy dolgot, és megakadt az iró szálam :oops: .
A memória továbbra is kúszik fel az égig, de legalább már nem szakad meg szegmentálási hibával... A maximum előtt megáll 1-2 megával.
A hangminőség így hagy maga után némi kívánni valót. A lock és unlock miatt néha elveszik egy-két tizedmásodpercnyi hanganyag, ami egy kicsit bosszantó, ha visszahallgatja az ember. De erre megpróbálok kitaslálni valami okosat.
Ha valami jó dolog még az eszetekbe jut, azt kérlek, írjátok le nekem (És más olvasónak).
Köszönöm a segítségeteket, biztos nem jutottam volna el idáig, ha nem vagytok!! Királyok vagytok! Mégegyszer köszi!

Üdv.: Stage 81

Hmm, ha nem kell feltétlenül a thread-queue-világmindenség bele, akkor szerintem egyszerűbb és gyorsabb lenne simán c-ben, egy szálon szimplán megnyitni a három fd-t, előre lefogni egy szép nagy 2xN-es statikus tömböt, 2 db int beolvasási index, 1 int kiírási, aztán a két bemeneti fd-t sasolni egy select()-tel, és ha valamelyiken van adat:
- a megfelelő beolvasási indexszel címzett helyre beírni az adatot a tömbbe, indexet léptetni körbeforgósan
- a kiírási indextől a két beolvasási közül a közelebbiig írkálni szépen kifelé file-ba és léptetni a kiírási indexet
- ha túlfutottunk (== az aktuális beolvasási index elérné a kiírásit), akkor bukta
- ha vége, akkor zárni az fd-ket és kilépni
Kódilag valami ilyesmi, bár ki épp nem próbáltam:
[code:1:9d60fd705c]
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <fcntl.h>
#include <sys/types.h>
#include <sys/time.h>
#include <sys/stat.h>

#define BUF_MAX 65536
#define max(a, b) (((a) > (b)) ? (a) : (b))
#define min(a, b) (((a) < (b)) ? (a) : (b))

int main(void)
{
int buf[BUF_MAX][2];
int pos_rd_left, pos_rd_right, pos_wr;
int fd_left, fd_right, fd_out;
fd_set rdset;
int do_quit, i, j, available_left, available_right, available;

fd_left = open("/dev/ize", O_RDONLY);
fd_right = open("/dev/bigyo", O_RDONLY);
fd_out = open("/tmp/valami.out", O_WRONLY | O_CREAT);

pos_rd_left = pos_rd_right = pos_wr = 0;
for (do_quit = 0; !do_quit; )
{
FD_ZERO(&rdset);
FD_SET(fd_left, &rdset);
FD_SET(fd_right, &rdset);
i = select(1 + max(fd_left, fd_right), &rdset, NULL, NULL, NULL);
if (i < 0)
break;

if (FD_ISSET(fd_left, &rdset))
{
i = read(fd_left, &(buf[pos_rd_left][0]), sizeof(int));
if (i != sizeof(int))
break;
pos_rd_left = (pos_rd_left + 1) % BUF_MAX;
if (pos_rd_left == pos_wr)
break;
}
if (FD_ISSET(fd_right, &rdset))
{
i = read(fd_right, &(buf[pos_rd_right][0]), sizeof(int));
if (i != sizeof(int))
break;
pos_rd_right = (pos_rd_right + 1) % BUF_MAX;
if (pos_rd_right == pos_wr)
break;
}

available_left = (pos_rd_left + BUF_MAX - pos_wr) % BUF_MAX;
available_right = (pos_rd_right + BUF_MAX - pos_wr) % BUF_MAX;
for (available = min(available_left, available_right); available > 0; available--)
{
/* Itt jon az osszegzes */
j = buf[pos_wr][0] + buf[pos_wr][1];

/* Ehelyett kell az osszeget kiiratni
i = write(fd_out, &(buf[pos_wr][0]), sizeof(int)); */
i = write(fd_out, &j, sizeof(int));
if (i != sizeof(int))
{
do_quit = 1;
break;
}
/* Es erre nincs tobbe szukseg
i = write(fd_out, &(buf[pos_wr][1]), sizeof(int));
if (i != sizeof(int))
{
do_quit = 1;
break;
}*/
pos_wr = (pos_wr + 1) % BUF_MAX;
}
}
close(fd_left);
close(fd_right);
close(fd_out);
return 0;
}
// vim:ts=4:noexpandtab:cino='':shiftwidth=4:
[/code:1:9d60fd705c]
Egyrészt minél egyszerűbb valami, annál hatékonyabb és megbízhatóbb, másrészt pedig minél kevesebb a nem általad írt kódrészlet benne, annál jobban ellenőrizhető, és annál kevesebbet szenvedsz más sara miatt :)...

Ja, jut is eszembe: a hangkártyáról biztos, hogy sizeof(int) byte-onként dől az adat?

Szia GSimon!

Hova küldhetem a söröket? ;)
Köszi a forrást és az ötletet, jövőhéten kipróbálom ( sajna előbb nem megy :(), az eredményről pedig hírt adok.
Nem biztos, hogy a mikrofonról intek jönnek... de az biztos, hogy adatok. A kezelésük, és file-ba rakásuk pedig mindegy milyen típusként történik, mert legközelebb értelmezni csak a hangkártya fogja. Az meg ugyan azt az adatot kéri. (Nálam legalább is jó minőségben műkszik)

Üdvözlettel:
Stage 81

Sziasztok!

Uhu linuxon KDevelop és Qt párossal fejlesztgetek. A programom két hangkártya mikrofon portját figyeli, és a róla érkező adatokat egyszerre írná ki egy file-ba (22050Hz). A problémám az, hogy file írás közben a memória nem szabadul fel. Úgy viselkedik, mintha a file is betöltődne a memóriába. Így pedig egy idő után megszakad a program, mert betelítődik a memória :-(

A következőket próbáltam eddig:
FILE *f; //Beállítottam, hogy ne legyen pufferelve (setbuf(f, NULL);)
QFile f; //Ennél is közvetlen írást állítottam be (f.open(IO_WriteOnly | IO_Raw);)
Mellette még használtam az fflush-t, sőt, tehetetlenségemben még azt is megpróbáltam, hogy folyamatosan zárogattam, nyitogattam a file-t. Sajnos semmi siker nem koronázta a próbálkozásaimat :-( Ha valaki tudna segíteni, annak nagyon örülnék!

Előre is köszönöm!
S81

A file lehet hogy nincs a memóriában, de a kiírandó adat igen. Valami rekurzív dolog nincs benne?

Lehet, hogy a magyarázkodásom között elveszett a lényeg, és ezért nem bír segíteni az sem, aki tudná a helyes megoldást...
Hogy lehet úgy file-ba írni, hogy az a memóriában ne jelenjen meg felesleges szemétként?
Ha erre nincs lehetőség, akkor hogy lehet az ilyen szemetet kitakarítani? (Ugyan is ha bezárom a file-t attól nem szabadul fel a memória!!!!)

Egyszerűsített példaprogram részlet:
[code:1:9b70135b6d]
#include "fejlec.h" //Ebben szerepelnek az osztályok leírásai

QPtrList <int> lista1;
QPtrList <int> lista2;

void * mikrofonOlvas1(void * arg){
rogzito *r = (rogzito *) arg;
int * adat;
while(r->rogzites){
adat = new int;
fread(adat, sizeof(int), 1, r->mikrofon1->fileLeíró);
lista1->append(adat);
}
}
void * mikrofonOlvas2(void * arg){
rogzito *r = (rogzito *) arg;
int * adat;
while(r->rogzites){
adat = new int;
fread(adat, sizeof(int), 1, r->mikrofon2->fileLeíró);
lista2->append(adat);
}
}
void * fileIr(void * arg){
rogzito *r = (rogzito *) arg;
int adat;
FILE *f;
if((f=fopen("allomany","wb"))==NULL){
printf("File nyitási hiba!");
exit(-1);
}
setbuf(f, NULL);
while(r->rogzites){
while(lista1.count()>0 && lista2.count()>0){
adat=* (int *) lista1.first();
delete lista1.first();
lista1.removeFirst();
adat+=* (int *) lista2.first();
delete lista2.first();
lista2.removeFirst();
fwrite(&adat, sizeof(adat), 1, f);
}
fflush(f); // <- Ez már csak szenvedés ;-)
}
fclose(f);
/* KIMARADT LISTAELEMEK FELSZABADÍTÁSA */
while(lista1.count()>0){
delete lista1.first();
lista1.removeFirst();
}
while(lista2.count()>0){
delete lista2.first();
lista2.removeFirst();
}
}

void rogzito::felvetelIndit(){
rogzites=TRUE;
pthread_create(&szal1, NULL, mikrofonOlvas1, this);
pthread_create(&szal2, NULL, mikrofonOlvas2, this);
pthread_create(&szal1, NULL, fileIr, this);
}
[/code:1:9b70135b6d]
Bocsi, hogy most csak így hírtelen összedobtam ezt (lehet, h. nem is működne), de jó volna rájönni, hogy miért nem ürül ki a memória úgy, ahogy kellene! És több szem, többet lát alapon... Ja! QFile-val is hasonló a helyzet! Sőt, ha csak szimplán egy értéket iratunk ki a file-ba, akkor sem szabadul fel a memória! Szóval tuti, hogy nem a listával van a gond!

A segítséget előre is köszönöm!

Üdv. S81

(Módosítottam, mert benne maradt egy fclose, ami szegmentálási hibát okozott!)
Bocsi, de megint csak egy kódrészletet szeretnék megosztani veletek. Ezt kipróbáltam szimpla C++ alatt, és ugyan azt a jelenséget okozza! Ha van kedvetek, próbáljátok ki ti is!

Fordítás:

g++ -o p proba.cpp -lpthread

A proba.cpp tartalma:
[code:1:0ee2de1100]
#include <stdio.h>
#include <stdlib.h>
#include <pthread.h>

void * FileIr(void * arg){
bool *szabad = (bool *) arg;
FILE *f;

int adat=100;
if((f=fopen("/home/stage/hello.bin", "wb"))==NULL){
printf("\nFile nyitási hiba!\n");
exit(-1);
}
do{
fwrite(&adat, sizeof(int), 1, f);
}while(*szabad);
fclose(f);

}
int main(int argv, char ** argc){
pthread_t szal1;
FILE *f;
bool * szabad= new bool;

int adat=100;
printf("Nyomjon <Enter> -t, és kezdődik a file írás\n");
getchar();

*szabad = true;
pthread_create(&szal1, NULL, FileIr, szabad);

printf("Nyomjon <Enter> -t, és befejeződik a fájl írás\n");
getchar();
*szabad = false;
printf("Nyomjon <Enter> -t, és befejeződik a program futása!\n");
getchar();
delete szabad;
}
[/code:1:0ee2de1100]

Vajon mi lehet a probléma?!?

Üdv.: S81

Ui.: Tudom, hogy ez a program tagolás nem kifejezetten objektum orientált. Bocsi érte, de az időm sajna korlátozva van, és így nem figyelhetek oda mindenre :-(

Ezt a második verziót kipróbáltam, de nálam nem fogyott el a memória.

A második verzió nálam sem szakadt meg. Viszont ha egy nagyobb program szerves része, és ez csak egy külön programszálon van, akkor már más a helyzet, ugyan is a többi szálon lehet más memóriafoglalás, azt pedig már nem kezeli le rendesen :-(
Szóval ha nézed mondjuk a rendszerfigyelőt, akkor látod, hogy a memória használat szép lassan kúszik felfelé, és még akkor sem esik vissza, ha az írás befejeződik, és bezárod a file-t :-(
Ez itt a méreg, nem a cián :-(

Egyébként köszönöm, hogy megpróbálsz segíteni!

Üdv. S81

Az első programhoz lennének kérdéseim, ill. megjegyzéseim:

Mitől 22050 Hz-es a mintavétel? A programból ez nem látszik.

Miért foglalsz le memóriát minden egyes int-nek? Ez idő és helypocsékolás.
A "new int" az int méretének a többszörösét fogja lefoglalni adminisztratív okok miatt.

Egyéb megjegyzések:

A listák olvasása/kiírása során csak akkor ír, ha érkeztek adatok mind a két mikrofonról. Ha csak az egyikről jönnek, akkor nem ír, és nem is szabadítja fel a foglalt helyet.
Szerintem az író thread-et kellene elsőnek indítani.

A mintavételezési sebesség szerintem csak másodlagos adat, lényegében nem számít. Ezt akár fel lehetne venni Cd minőségre is... Bár mivel 2 hangkariról van szó, lényegében a memóriában helyet kapó terület akkora, mint ha 1 kariról cd minőségben vennék fel (2*22050 = 44100)
Az idő pocséklással egyet értek, viszont a helyfoglalást nem hiszem, hogy annyira megdobná...
az adat-ra mutató pointer memória területe állandó, hiszen az nem változik: Ez 2 byte
maga az adatrész (mely folyamatosan foglalódik), az 4 byte. Ráadásul, (ha jól emlékszem) ha az így lefoglalt memóriaterületet felszabadítod, miután bekerül a listába, akkor a lista eleme is változik. (Leegyszerűsítve, az adat NULL lesz, és így nem lesz mit kiírni a fájlba. Bár ebben nem vagyok biztos, mindjárt utánna nézek)

Addig is üdv: S81

[quote:b293618101="popacsek"]Egyéb megjegyzések:

A listák olvasása/kiírása során csak akkor ír, ha érkeztek adatok mind a két mikrofonról. Ha csak az egyikről jönnek, akkor nem ír, és nem is szabadítja fel a foglalt helyet.
Szerintem az író thread-et kellene elsőnek indítani.

Ez így van. De ha üres a lista, akkor nincs is mit törölni - felszabadítani. Egyébként meglepő, de gyorsabban ír ki file- ba, mint ahogy telítődik a lista. (Ha a belső while ciklus után kiíratod a listák méretét, akkor elkezd szaladni a képernyőd)
Egyébként kicsit fejlettebb már a programom, mint ahogy azt ide írtam. Már korlátozva van az is, hogy a két lista elemszáma között nem lehet 100-nál nagyobb a különbség (Úgy ahogy összehangoltam a két listát... az a pár tízezred késést, ami e miatt történik, azt nyugodtan bárki a kontómra írhatja, már ha észreveszi benne)

[quote:29639df86f="popacsek"]Miért foglalsz le memóriát minden egyes int-nek? Ez idő és helypocsékolás.
A "new int" az int méretének a többszörösét fogja lefoglalni adminisztratív okok miatt.

Utánna néztem a dolognak. Ha egy olyan mutatót adsz át a QPtrList-nek, amit később felszabadítasz, akkor a lista adatai "értéktelenné" válnak. Tehát a lista feltöltésem nem hagy kívánni valót maga után .
Egyébb építő jellegű észrevétel? Én már csumára kifogytam az ötletekből :-(
Már azt is megpróbáltam, hogy megadok neki egy puffer részt, amit fflush-sal megpróbálok a FILE-ba súlykolni, de hiába :-(

Üdv.: S81

[quote:9aa281b352="stage81"] Utánna néztem a dolognak. Ha egy olyan mutatót adsz át a QPtrList-nek, amit később felszabadítasz, akkor a lista adatai "értéktelenné" válnak. Tehát a lista feltöltésem nem hagy kívánni valót maga után .

Nem értek veled teljesen egyet. Bár lehet, hogy a probléma nem ebből fakad, de az általad használt adatszerkezet DURVA pocséklás.

A QPtrList/new int helyett megpróbálkoznék az stl::queue-val. Bár nem tudom, hogy hogyan implementálták a queue-t ...

Talán kötekedésnek tünik a "durva pocséklás", ezért elmagyarázom, miért írtam.

A "new int" - bár nem tudom megmondani mennyivel - de többet foglal le 4 byte-nál (azt hiszem kb. minden new hívás +8 byte-ot jelent).

A QPtrList-ben van egy adatra mutató pointer (+4 byte), mivel lista, feltételezem van benne egy-egy pointer a lista előző és következő elemére (+8 byte). Ha a lista "láncszemei" is külön-külön foglalódnak le, akkor ez ismét +8 byte.
Tehát az egy int-nek lefoglalt hely a 4byte helyett kb. 32 byte!

Sziasztok!

Átnéztem GSimon kódját. Nekem tetszik a kivitelezés. (Eszembe juthatott volna nekem is a multiplexelés, de nem jutott :oops: ) Így még a proci idő is lent marad (thread-nél a folyamatos ciklus felviszi 100 %-ra).
Ami sajnálatos, hogy a memória így is növekvő tendenciát mutat. Gondoltam, "finomítom" egy kicsit a file műveleteket, de ez nem igazán jött össze. Az O_SYNC -kel próbálkoztam, de így sajna rengeteg adat elveszik ( a 22 MHz-es anyagból kb 7 MHZ-es lesz).
A kód így néz ki:
[code:1:090ef9c812]fd_out = open("proba.wav", O_WRONLY | O_CREAT | O_TRUNC | O_SYNC, 0644);[/code:1:090ef9c812]
A kérdésem a következő lenne:
- Honnan lehet tudni O_SYNC-nél, hogy az írási művelet sikeresen megtörtént? Sajnos a write visszatérési érték megfelelő, tehát ezzel kiszürni nem tudom :(

Előre is, és utólag is minden választ és segítő szándékot köszönök!
Üdv.: S81

Sziasztok!

Megpróbáltam az fdatasync-et, de ez sem hozta meg a várt sikert :( Ha lehet azt mondani, még talán több adat veszik el
A for ciklus után helyeztem el.
[code:1:cdedd2bc34]
for (available = min( available_left, available_right); available > 0; available--){
buf[pos_wr][0]+=buf[pos_wr][1];
i = write(fd_out, &(buf[pos_wr][0]), sizeof(int));

if (i != sizeof(int)){
perror("write");
*p->szabad=0;
break;
}
pos_wr = (pos_wr + 1) % BUF_MAX;
}
fdatasync(fd_out);
[/code:1:cdedd2bc34]

Üdv.: Stage 81

[quote:084913214d="popacsek"]A QPtrList-ben van egy adatra mutató pointer (+4 byte), mivel lista, feltételezem van benne egy-egy pointer a lista előző és következő elemére (+8 byte).

Ez tagadhatatlan, a többiben nem vagyok biztos. Holnap utánna nézek a queue-nak, most sajna mennem kell

A segítségedet köszönöm, remélem holnap is részesülök belőle!

Üdv.: Stage81

Ui.: Nem 2 byte egy mutató mérete? ff:ff Vagy csak maga a szegmens cím 2 byte?

Azt elfelejtettem még leírni, hogy ha nem használok O_SYNC-et, akkor a program bezárása után is megmarad a memóriában a "szemét"

stage, biztos, hogy igazak a dolgok, amit a memóriafoglalásról írsz?
szerintem az a program, amivel kiíratod a szabad memória mennyiségét, az nem jó, és az oprencer file cache-t is beleveszi

és tényleg a jó öreg C teljesítményigényes helyekre sokkal jobb, mint lockolás és tsai

Na igen, legalább egy ponton elszúrtam :oops:, nevezetesen ha jól vettem ki, te összegezni akarod a két mikrofon adatait ("adat +="), az én változatom meg csak összefűzi, azaz kétszer annyit ír, mint kéne, ezzel a freki már alapból feleződik. Át is javítom a fenti kódban rögtön.
Amúgy az O_SYNC-nek elvben mennie kéne, csak az tényleg lassít. Alternatív megoldás időnként meghívni egy fdatasync(fd_out)-ot.
Kilépés után viszont elvileg csak addig maradhat memória használatban, amíg ki nem írja a cache-t a vinyóra. Ma már nem ígérem, de holnap v. holnapután kipróbálom, aztán akkor csak többet tudok majd szólni a dologhoz :).

Király vagy, GSimon! Köszönöm a segítségedet!

Én is észrevettem pár hibát, ami tulajdon képpen nem hiba, csak egy kis "hiány" (Pl.: mikrofon beállítása, file kiírása). De a forrásban amit írtál, nem az adatok kiírásának a mikéntje a lényeg, hanem maga az ötlet! Pl nekem meg sem fordult a fejemben a select használata, pedig evvel lényegesen egyszerűsödik a forráskód áttekinthetősége, plusz kevesebb a hibalehetőség is ! Szóval le a kalappal előtted!

Az fdatasync-et mindjárt megnézem, és ha működni fog, akkor azonnal visszajelzek!

A file bezárás után valóban logikusnak tűnik, hogy kiürítse a memóriát, de eddigi tapasztalataim szerint ezt sajnos nem teszi meg. Sőt, a program bezárása után sem ürül ki a memória, ami szerintem eget verően nagy probléma! (Pedig egy deka dinamikus foglalás sincs benne, csak statikus változók.)

Üdvözlettel:
Stage 81

Helló!

Mit mondjak... Csumára igazad van. Valóban érdemesebb sor adatszerkezetet használni ilyen esetekre. (Ismerős volt nagyon ez a queue, de nem bírtam tegnap hírtelen mihez kapcsolni) Már át is írtam a progit. Sajnos a hiba így is fenn áll :-( Igaz, nem találtam qt-ban stl-t, így a felajánlott qptrqueue-t építettem be a szoftba.
Egyébként nállad valóban nem nyomta meg a második verzió a memória használatot?

Üdv.: S81