2010-03-10 1 views
11

Ich schreibe eine Anwendung muss große Audio-Multi-Samples, in der Regel etwa 50 MB Größe verwenden. Eine Datei enthält ca. 80 einzelne kurze Tonaufnahmen, die jederzeit von meiner Anwendung wiedergegeben werden können. Aus diesem Grund werden alle Audiodaten für einen schnellen Zugriff in den Speicher geladen.So führen Sie plattformübergreifende asynchrone Datei-E/A in C++ aus

Wenn Sie eine dieser Dateien laden, kann es jedoch einige Sekunden dauern, sie in den Speicher zu legen, da ich eine große Datenmenge mit ifstream lesen muss, was bedeutet, dass meine Programm-GUI vorübergehend eingefroren ist. Ich habe versucht, meine Datei zu speichern, aber das verursacht riesige CPU-Spitzen und ein Chaos von Audio jedes Mal, wenn ich zu einem anderen Bereich der Datei springen muss, was nicht akzeptabel ist.

Das hat mich dazu gebracht zu denken, dass die Durchführung einer asynchronen Datei lesen mein Problem lösen wird, das heißt, die Daten werden in einem anderen Prozess gelesen und ruft eine Funktion bei Abschluss. Dies muss sowohl für Mac OS X und Windows als auch für C++ kompatibel sein.

EDIT: Ich möchte nicht die Boost-Bibliothek verwenden, weil ich eine kleine Codebasis behalten möchte.

+0

Re: Boost.asio, es existiert auch als eigenständige Version, siehe http://think-async.com/ – Hasturkun

+0

Sie können Ihre Daten auch in kleineren Chunks lesen, die nicht so viel Zeit kosten würden, dann lassen Sie die Event-Schleife dazwischen laufen. – kashiraja

Antwort

8

Boost hat eine Asio-Bibliothek, die ich vorher nicht benutzt habe (sie ist nicht auf der Liste der zugelassenen Bibliotheken von Drittanbietern auf der NASA).

Meine eigene Herangehensweise war es, den Code für das Lesen von Dateien zweimal zu schreiben, einmal für Windows, einmal für die API von POSIX aio, und dann einfach den richtigen zum Verknüpfen auswählen.

Verwenden Sie für Windows OVERLAPPED (Sie müssen es im CreateFile-Aufruf aktivieren und dann beim Lesen eine OVERLAPPED-Struktur übergeben). Sie können entweder festlegen, dass ein Ereignis abgeschlossen wird (ReadFile), oder einen Abschlussrückruf aufrufen (ReadFileEx). Sie müssen wahrscheinlich Ihre Hauptereignisschleife ändern, um MsgWaitForMultipleObjectsEx zu verwenden, so dass Sie entweder auf die I/O-Ereignisse warten oder das Ausführen von Callbacks zusätzlich zum Empfangen von WM_-Fenstermeldungen erlauben können. MSDN verfügt über Dokumentation für diese Funktionen.

Für Linux gibt es entweder fadvise und epoll, die den Readahead-Cache verwenden, oder aio_read, der tatsächliche asynchrone Leseanforderungen erlaubt. Nach Abschluss der Anfrage erhalten Sie ein Signal, mit dem Sie eine XWindows-Nachricht senden und Ihre Ereignisverarbeitungsschleife aktivieren können.

Beide sind ein wenig anders in den Details, aber der Nettoeffekt ist der gleiche - Sie fordern eine Lesung, die im Hintergrund abgeschlossen, dann wird Ihre Ereignis Dispatch-Schleife aufgeweckt, wenn die I/O beendet.

+0

Ja, ich musste vorher ein paar Dinge zweimal schreiben, eins für Windows eins für POSIX, also wäre das kein Problem. Wo kann ich Asynchrone Datei-I/O für POSIX und Windows lesen, damit ich es schreiben kann? Ich möchte Boost nicht verwenden, weil ich meine kleine Codebasis behalten möchte. – orgazoid

+0

MSDN für Windows, Manpages für Linux und Google ist auch großartig. Ich habe meine Antwort so bearbeitet, dass sie beschreibt, wie es funktioniert, und Ihnen die Namen der wichtigsten Funktionen genannt, die Sie erforschen möchten. –

2

Die Boost.Asio-Bibliothek verfügt über eine begrenzte Implementierung von asynchronen Datei-E/A-Operationen (nur Windows-Wrapper für HANDLE), daher ist sie nicht für Sie geeignet. Siehe auch this Frage.

Sie könnten Ihre eigenen asynchronen Lesen mit Standard-Streams und Boost.Thread-Bibliothek (oder plattformspezifische Threads-Unterstützung) einfach implementieren.

+0

Das ist Multithreading, keine asynchrone I/O, es lässt den Programmierer für die Synchronisierung des Zugriffs über Threads verantwortlich, und das Beheben von Anfragen ist ein echter Schmerz. Verwenden Sie stattdessen echte Async-Lesevorgänge. –

Verwandte Themen