2013-02-07 14 views
5

Mam dwa pliki wykonywalne napisane w C++ w systemie Windows. Generuję niektóre dane w jednym i chcę wywołać inny plik wykonywalny, aby przetworzyć te dane. Mógłbym zapisać dane do pliku, a następnie odczytać je w innym pliku wykonywalnym, ale wydaje się to dość kosztowne pod względem dyskowych operacji we/wy. Jaki jest lepszy sposób na zrobienie tego? Wydaje się, że jest to dość proste pytanie, ale Google nie pomaga!Przesyłanie danych między plikami wykonywalnymi

Załóżmy, że dane mają około 100 MB i są generowane w całości przed wysłaniem żądania (tzn. Nie jest konieczne przesyłanie strumieniowe).

Odpowiedzi, które działają podczas mieszania procesów 32- i 64-bitowych, zyskują dodatkowe punkty.

+3

nazwane potoki, lokalne zwycięskie gniazda, pliki z mapami pamięci, pamięć współdzielona, ​​gniazdo poczty, rejestr, komunikaty okna (nieodpowiednie dla dużych danych), co jeszcze? wybierz. jeśli powiesz nam trochę więcej o danych (rozmiarach, itp.) i charakterze, któremu chcesz udostępnić dane, możemy podać lepszą radę, jeśli chodzi o najlepszą metodę. – thang

+1

Ogólnie nazywa się to [komunikacja między procesami] (http://en.wikipedia.org/wiki/Inter-process_communication). – Oswald

+0

Pewnie, dodałem trochę informacji o danych. Pierwotnie napisałem "dużą ilość", ale zredagowałem moje pytanie przed opublikowaniem, naprawdę powinienem podać kilka liczb :) –

Odpowiedz

4

Jeśli twoje procesy można łatwo zapisywać i czytać z pliku, po prostu idź dalej. Utwórz plik, podając CreateFile i oznacz go jako tymczasowy &. Windows używa tej wskazówki, aby opóźnić fizyczne zapisy, ale wszystkie semantyki plików są nadal przestrzegane. Ponieważ twój plik ma tylko 100 MB i jest aktywny w użyciu, Windows prawie na pewno jest w stanie utrzymać jego zawartość w pełni w pamięci RAM.

+0

Ok, nie wiedziałem, że ten rodzaj buforowania jest niezawodny. Zdecydowanie najprostsze rozwiązanie, dzięki :) –

3

Można użyć Boost.MPI. To z Boost, która ma wysoki standard jakości, a próbki kodu wydaje się dość wyraźne:

http://www.boost.org/doc/libs/1_53_0/doc/html/mpi/tutorial.html#mpi.point_to_point

// The following program uses two MPI processes to write "Hello, world!" 
// to the screen (hello_world.cpp): 

int main(int argc, char* argv[]) 
{ 
    mpi::environment env(argc, argv); 
    mpi::communicator world; 

    if (world.rank() == 0) { 
    world.send(1, 0, std::string("Hello")); 
    std::string msg; 
    world.recv(1, 1, msg); 
    std::cout << msg << "!" << std::endl; 
    } else { 
    std::string msg; 
    world.recv(0, 0, msg); 
    std::cout << msg << ", "; 
    std::cout.flush(); 
    world.send(0, 1, std::string("world")); 
    } 
    return 0; 
} 
+0

Zwiększenie nigdy nie przestaje mnie zadziwiać! Wydaje się, że jest to dobra opcja, szczególnie jeśli rozszerzę ją, aby działała na wielu komputerach, ale na razie pójdę z prostszą opcją polegania na buforowaniu plików, jak sugeruje MSalters. –

1

Zakładając, że tylko chce iść „w jednym kierunku” (czyli nie trzeba aby uzyskać dane BACK z procesu potomnego), można użyć _popen(). Zapisujesz dane do potoku, a proces potomny odczytuje dane z stdin.

Jeśli potrzebujesz dwukierunkowego przepływu danych, musisz użyć dwóch rur, jednej jako wejściowej, a drugiej jako wyjściowej, i będziesz musiał skonfigurować schemat, w jaki sposób proces podrzędny łączy się z tymi rurami [możesz nadal ustawiaj stdin/stdout jako ścieżkę danych, ale możesz również użyć pary nazwanych potoków].

Trzecią opcją jest region shared memory. Nigdy tego nie robiłem w systemie Windows, ale zasada jest prawie taka sama jak w przypadku Linuksa [i wielu lat wstecz w OS/2]: 1. Utwórz w regionie macierzystym region pamięci o danej nazwie proces. 2. Proces potomny otwiera ten sam obszar pamięci. 3. Dane są przechowywane przez proces macierzysty i czytane przez proces potomny. 4. Jeśli to konieczne, semafory lub podobne mogą być używane do sygnalizowania ukończenia/wyników gotowych/etc.

+1

Dowiedziałem się czegoś nowego :) Dzięki! Rury brzmią jak dobra opcja, ale przypuszczam, że pamięć współdzielona implikuje dzieloną przestrzeń adresową, która nie działałaby podczas mieszania procesów 32- i 64-bitowych. –

+0

Jak już nie próbowałem, nie wiem, ale uważam, że dopóki używasz nazwanej pamięci współdzielonej i nie przekraczasz limitu adresu 32-bitowego [czyli mniej niż 2 GB], to powinno działać. Pamiętaj tylko, aby nie umieszczać wskaźników w pamięci współdzielonej. Pamięć nie jest (koniecznie) udostępniana pod tym samym adresem. –

+0

Ach, dobrze, źle zrozumiałem próbkę kodu. Tak, wygląda na to, że działa w ten sposób. Dzięki x2! –

Powiązane problemy