Gyermekprojekt létrehozása átcsoportosított bemenettel és kimenettel

Gyermekprojekt létrehozása átcsoportosított bemenettel és kimenettel

A példa ebben a részben bemutatja, hogyan hozzon létre egy gyermekfolyamatot a konzol folyamatából. Ezenkívül bemutatja a nem nevesített programcsatornák használatának technikáját, hogy a gyermekprobléma bemeneti és kimeneti standard leírásait átrendezze.

A CreatePipe függvény a SECURITY_ATTRIBUTES struktúrát használja. Létrehozhat öröklődő leírókat az olvasáshoz és az íráshoz a két csatorna vége felé. Az egyik csatorna olvasásának vége a gyermekprobléma standard bemenetként szolgál, és a másik csatorna rekordjának vége a gyermekfolyamat szabványos kimenete. Ezek a csatornaleírók a SetStdHandle függvényben vannak beállítva. ami a gyermek folyamat által örökölt szabványos leírásokat tesz. A gyermekfolyamat létrehozása után a SetStdHandle ismét felhasználásra kerül a szülői folyamat szabványos forrásleíróinak visszaállításához.

A szülőfolyamat a csatornák másik végét használja a bemeneti adatok írásához és a gyermek folyamatadatok kimenetének olvasásához. A csatorna ezen végeinek leírói szintén örökletesek. A leírót azonban nem szabad örökölni. Gyermekprojekt létrehozása előtt a szülőfolyamatnak a DuplicateHandle programot kell használnia. A hChildStdinWr program által definiált globális változó duplikátumának létrehozása. amely nem örökölhető. Akkor használja a CloseHandle-t. hogy lezárja az örökölt fogantyút. További információt a Csatornák fejezetben talál.

A következő a szülőfolyamat.

#defineBUFSIZE 4096

HANDLE hChildStdinRd, hChildStdinWr, hChildStdinWrDup,

hChildStdoutRd, hChildStdoutWr, hChildStdoutRdDup,

hInputFile, hSaveStdin, hSaveStdout;

BOOLCreateChildProcess (VOID);

VOIDReadFromPipe (VOID);

// Állítsa be a bInheritHandle jelzőt, mivel a csatornaleírók öröklődnek.

saAttr.nLength = sizeof (SECURITY_ATTRIBUTES);

// Az STDOUT újbóli hozzárendelése a gyermekprocesszhez

// 1. Mentse az aktuális STDOUT-ot, amelyet később visszaállít.

// 2. Hozzon létre egy névtelen csatornát, amely a gyermek folyamat STDOUT-ja lesz.

// 3. Állítsa be a szülőfolyamat STDOUT értékét,

// a csatorna rekord leírása az örökölt gyermekprocesszel.

// 4. Hozzon létre az olvasási leíró nem örökölt másolatát és zárja be

// öröklött olvasási leíró.

// Mentse az aktuális STDOUT leíróját.

hSaveStdout = GetStdHandle (STD_OUTPUT_HANDLE);

// Hozzon létre egy csatornát a gyermekprocesszus STDOUT-jához.

ha (! CreatePipe (hChildStdoutRd, hChildStdoutWr, saAttr, 0))

ErrorExit ("Stdout cső létrehozása sikertelen \ n");

// Állítsa be a csatorna rekord leíróját, amely az STDOUT lesz.

ha (! SetStdHandle (STD_OUTPUT_HANDLE.hChildStdoutWr))

ErrorExit ("Az STDOUT átirányítása sikertelen");

// Hozzon létre egy nem kezelt olvasási leíró és zárja be az örökölt olvasási leíró.

fSuccess = DuplicateHandle (GetCurrentProcess (), hChildStdoutRd,

GetCurrentProcess (), hChildStdoutRdDup. 0

ErrorExit ("DuplicateHandle failed");

// Az STDIN újbóli hozzárendelése a gyermekprocesszhez:

// 1. Mentse az aktuális STDIN-et, amelyet később visszaállít.

// 2. Hozzon létre egy névtelen csatornát, amely a gyermek folyamat STDIN lesz.

// 3. Állítsa be a szülőfolyamat STDIN-jét, ami a leíró

// olvasd el a csatornát, hogy örököljön a gyermek folyamat.

// 4. Hozzon létre a rekord leírójának nem örökölt példányát

// A rekord örökölt leírója.

// Mentse az aktuális STDIN leírását.

hSaveStdin = GetStdHandle (STD_INPUT_HANDLE);

// Hozzon létre egy csatorna a gyermekprocesszus STDIN-jéhez.

ha (! CreatePipe ( hChildStdinRd, hChildStdinWr, saAttr, 0))

ErrorExit ("Stdin cső létrehozása sikertelen \ n");

// Állítsa be az olvasási leírót a csatorna számára, amely STDIN lesz.

ha (! SetStdHandle (STD_INPUT_HANDLE.hChildStdinRd))

ErrorExit ("Stdin átirányítása sikertelen");

// Duplikálja a csatorna írófogantyúját, így nem örökölt.

fSuccess = DuplicateHandle (GetCurrentProcess (), hChildStdinWr,

GetCurrentProcess (), hChildStdinWrDup, 0,

FALSE, // nem örökli

ErrorExit ("DuplicateHandle failed");

// Most hozd létre a gyermekproblémát.

ErrorExit ("Probléma létrehozása sikertelen");

// A folyamat létrehozása után állítsa vissza a mentett STDIN és STDOUT fájlokat.

ha (! SetStdHandle (STD_INPUT_HANDLE.hSaveStdin))

ErrorExit ("A Stdin átirányítása nem sikerült \ n");

ha (! SetStdHandle (STD_OUTPUT_HANDLE.hSaveStdout))

ErrorExit ("A Stdout ismételt átirányítása nem sikerült \ n");

// Szerezd meg a szülő bemeneti fájljának leíróját.

hInputFile = CreateFile (argv [1], GENERIC_READ. 0, NULL,

OPEN_EXISTING. FILE_ATTRIBUTE_READONLY. NULL);

ha (hInputFile == INVALID_HANDLE_VALUE)

ErrorExit ("nincs bemeneti fájl \ n");

// Írja be a csatornát, ami a gyermek szokásos adatbevitele

// A csatorna olvasása, amely a gyermek szokásos kimenete