Blackthorne schrieb:
Und jetzt, wo ich diese Worte schreibe, wird mir klar, dass ich entweder eine blockierende Sendeoperation nutzen muss, die erst dann zurückkehrt, wenn die Nachricht verschickt wurde, oder aber ich muss den Puffer intern kopieren, damit der User nicht von außen in den Speicherbereich schreibt, während das MPI-Laufzeitsystem diesen ausliest.
Wir stellen fest: Ein solches Forum ist gleich doppelt sinnvoll. Viele Dinge erklärt man sich hier selbst.
Wenn kopieren kein Problem ist, dann kopiere. Ist das einfachste. Dann brauchst du den ganzen Puffer quargel nurmehr intern, deine Sendefunktion nimmt dann einfach einen void* (char*, T* - was auch immer) und ein size_t. Die kopiert dann einfach alles bevor sie zurückkehrt, fertig.
Oder aber du machst irgendwas ala (C-Style, wenn du nur ein C++ Interface brauchst sähe das natürlich eleganter aus):
struct Buffer; // opaque, wird also nicht in einem öffentlichen Header File definiert
Buffer* CreateBuffer(size_t size);
void* GetBufferPtr(Buffer* buffer);
size_t GetBufferSize(Buffer* buffer);
int IsBufferBusy(Buffer* buffer); // != 0 wenn er noch vom System verwendet wird, sonst 0
void WaitBuffer(Buffer* buffer); // wartet auf IsBufferBusy() == 0
void FreeBuffer(Buffer* buffer); // hau weg den Scheiss
Oder, noch eine andere Möglichkeit: du verlangst vom Client einfach dass er sich für jedes "send" einen neuen Buffer vom der Library holt - dann kann auch nie unklar sein wann der Buffer "wiederverwendet" werden darf, da er nie wiederverwendet werden darf. Dazu gibts dann natürlich eine "Buffer den ich doch nicht brauce wieder freigeben" Funktion, für Fälle wo der Client aus irgendeinem Grund einen Buffer angefordert hat, aber den doch nicht abschicken will.
Am einfachsten (für den User) ist natürlich die "Daten kopieren" Variante, bei den anderen beiden kann es schnell passieren dass unachtsame oder einfach zu doofe/konfuse User Fehler machen, die dann schwer zu finden sind.
Nochwas: die "Daten kopieren" Variante lässt sich kaum bzw. garnicht mit einer "non-blocking Garantie" verbinden. Deine Library kann ja nicht unendlich viel Speicher anfordern. Die einzigen 2 Möglichkeiten die mir dazu einfallen: entweder ala non-blocking Berkeley Sockets, d.h. "send()" liefert einfach "geht nicht" zurück wenn alle internen Buffer schon voll sind, oder aber "send()" blockiert in dem Fall dass alle Buffer voll sind einfach solange bis irgendwo was frei wird. Im 2. Fall könnte es allerdings günstig sein dem User eine Möglichkeit geben eine gewisse Mindestgrösse für die internen Buffer vorzugeben (oder vorzuschlagen) -- ob das nötig ist kommt natürlich drauf an ob die Library nicht sowieso eine in jedem Fall ausreichende/ideale Grösse selbst ermitteln kann.
Achherrjeh, ist wieder lange geworden.
Ich hoffe nur ich hab jetzt nicht nur Zeugs geschrieben was dir eh schon klar ist...