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