Volver al temario
Tema 03 · 54 páginas

La gestión de procesos

Tema completo Modo estudio
TEXTO ORIGINAL · Páginas 3741 Ver PDF

4.2.2. Los cambios del entorno que configura un proceso

Texto íntegro de la conversión. Las figuras y la disposición de las notas se pueden consultar en el PDF.

4.2.2. Los cambios del entorno que configura un proceso

El siguiente ejemplo muestra cómo se puede crear un proceso en Windows y cómo se puede realizar la redirección de las entradas y las salidas por medio de los manejadores (handles). Mostramos sólo algunos trozos que ilustran cómo se puede realizar la redirección. El ejemplo usa pipes. Aunque estudiaremos con detalle las pipes en el último módulo del curso, hemos visto ya su funcio-

Página 38

namiento básico al hablar del intérprete de comandos y la creación de filtros conectando la salida de unos comandos con la entrada de otros comandos. El ejemplo completo se puede encontrar en la web de ayuda a los desarrolladores de Microsoft bajo el concepto "Creating a Child Process with Redirected Input and Output".

El código del padre contiene:

... HANDLE g_hChildStd_IN_Rd = NULL;

HANDLE g_hChildStd_IN_Wr = NULL; HANDLE g_hChildStd_OUT_Rd = NULL; HANDLE g_hChildStd_OUT_Wr = NULL;

... int _tmain(int argc, TCHAR *argv[]) {

SECURITY_ATTRIBUTES saAttr;

printf("\n->Start of parent execution.\n");

// Set the bInheritHandle flag so pipe handles are inherited.

saAttr.nLength = sizeof(SECURITY_ATTRIBUTES); saAttr.bInheritHandle = TRUE; saAttr.lpSecurityDescriptor = NULL;

// Create a pipe for the child process's STDOUT. ¡if (! CreatePipe(&g_hChildStd_OUT_Rd, &g_hChildStd_OUT_Wr, &saAttr, 0))

ErrorExit(TEXT("StdoutRd CreatePipe"));

// Ensure the read handle to the pipe for STDOUT is not inherited. ¡if (! SetHandleInformation(g_hChildStd_OUT_Rd, HANDLE_FLAG_INHERIT, 0)) ErrorExit(TEXT("Stdout SetHandleInformation"));

// Create a pipe for the child process's STDIN. ¡if (! CreatePipe(&g_hChildStd_IN_Rd, &g_hChildStd_IN_Wr, &saAttr, 0))

ErrorExit(TEXT("Stdin CreatePipe"));

// Ensure the write handle to the pipe for STDIN is not inherited.

¡if (! SetHandleInformation(g_hChildStd_IN_Wr, HANDLE_FLAG_INHERIT, 0)) ErrorExit(TEXT("Stdin SetHandleInformation"));

// Create the child process. CreateChildProcess();

... }

Página 39

void CreateChildProcess()

// Create a child process that uses the previously created pipes for STDIN and STDOUT. { TCHAR szCmdline[]=TEXT("child");

PROCESS_INFORMATION piProcInfo; STARTUPINFO siStartInfo; BOOL bSuccess = FALSE;

// Set up members of the PROCESS_INFORMATION structure.

ZeroMemory( &piProcInfo, sizeof(PROCESS_INFORMATION));

// Set up members of the STARTUPINFO structure.

// This structure specifies the STDIN and STDOUT handles for redirection. ZeroMemory( &siStartInfo, sizeof(STARTUPINFO)); siStartInfo.cb = sizeof(STARTUPINFO);

siStartInfo.hStdError = g_hChildStd_OUT_Wr; siStartInfo.hStdOutput = g_hChildStd_OUT_Wr; siStartInfo.hStdInput = g_hChildStd_IN_Rd;

siStartInfo.dwFlags |= STARTF_USESTDHANDLES;

// Create the child process.

bSuccess = CreateProcess(NULL, szCmdline // command line NULL // process security attributes

NULL // primary thread security attributes TRUE // handles are inherited 0 // creation flags

NULL // use parent's environment NULL // use parent's current directory

&siStartInfo // STARTUPINFO pointer &piProcInfo); // receives PROCESS_INFORMATION

// If an error occurs, exit the application. ¡if (! bSuccess) ErrorExit(TEXT("CreateProcess"));

else { // Close handles to the child process and its primary thread.

CloseHandle(piProcInfo.hProcess); CloseHandle(piProcInfo.hThread); }

}

El código del hijo es:

#include <windows.h>

Página 40

#include <stdio.h>

#define BUFSIZE 4096

int main(void)

{ CHAR chBuf[BUFSIZE]; DWORD dwRead, dwWritten;

HANDLE hStdin, hStdout; BOOL bSuccess;

hStdout = GetStdHandle(STD_OUTPUT_HANDLE); hStdin = GetStdHandle(STD_INPUT_HANDLE);

if ( (hStdout == INVALID_HANDLE_VALUE) || (hStdin == INVALID_HANDLE_VALUE)

) ExitProcess(1);

// Send something to this process's stdout using printf. printf("\n ** This is en message from the child process. ** \n");

// This simple algorithm uses the existence of the pipes to control execution. // It relies on the pipe buffers to ensure that no data is lost. // Larger applications would use more advanced process control.

for (;;) {

// Read from standard input and stop on error or no data. bSuccess = ReadFile(hStdin, chBuf, BUFSIZE, &dwRead, NULL);

¡if (! bSuccess || dwRead == 0) break;

// Write to standard output and stop on error. bSuccess = WriteFile(hStdout, chBuf, dwRead, &dwWritten, NULL);

¡if (! bSuccess) break;

} return 0; }

Página 41

Ver fragmento extraído sin normalizar
4.2.2.  Los cambios del entorno que configura un proceso


El siguiente ejemplo muestra cómo se puede crear un proceso en Windows y
cómo se puede realizar la redirección de las entradas y las salidas por medio de
los manejadores (handles). Mostramos sólo algunos trozos que ilustran cómo
se puede realizar la redirección. El ejemplo usa pipes. Aunque estudiaremos
con detalle las pipes en el último módulo del curso, hemos visto ya su funcio-

## Página 38

<!-- source-page: 38 -->

GNUFDL • PID_00214802                                                                                  38                                                                                                      La gestión de procesos

namiento básico al hablar del intérprete de comandos y la creación de filtros
conectando la salida de unos comandos con la entrada de otros comandos. El
ejemplo completo se puede encontrar en la web de ayuda a los desarrolladores
de Microsoft bajo el concepto "Creating a Child Process with Redirected Input
and Output".


El código del padre contiene:


    ...
    HANDLE g_hChildStd_IN_Rd = NULL;

    HANDLE g_hChildStd_IN_Wr = NULL;
    HANDLE g_hChildStd_OUT_Rd = NULL;
    HANDLE g_hChildStd_OUT_Wr = NULL;

    ...
    int _tmain(int argc, TCHAR *argv[])
    {


      SECURITY_ATTRIBUTES saAttr;


      printf("\n->Start of parent execution.\n");


      // Set the bInheritHandle flag so pipe handles are inherited.

      saAttr.nLength = sizeof(SECURITY_ATTRIBUTES);
      saAttr.bInheritHandle = TRUE;
      saAttr.lpSecurityDescriptor = NULL;


      // Create a pipe for the child process's STDOUT.
      ¡if (! CreatePipe(&g_hChildStd_OUT_Rd, &g_hChildStd_OUT_Wr, &saAttr, 0))

        ErrorExit(TEXT("StdoutRd CreatePipe"));


      // Ensure the read handle to the pipe for STDOUT is not inherited.
      ¡if (! SetHandleInformation(g_hChildStd_OUT_Rd, HANDLE_FLAG_INHERIT, 0))
        ErrorExit(TEXT("Stdout SetHandleInformation"));


      // Create a pipe for the child process's STDIN.
      ¡if (! CreatePipe(&g_hChildStd_IN_Rd, &g_hChildStd_IN_Wr, &saAttr, 0))

        ErrorExit(TEXT("Stdin CreatePipe"));


      // Ensure the write handle to the pipe for STDIN is not inherited.

      ¡if (! SetHandleInformation(g_hChildStd_IN_Wr, HANDLE_FLAG_INHERIT, 0))
        ErrorExit(TEXT("Stdin SetHandleInformation"));


      // Create the child process.
      CreateChildProcess();


    ...
    }

## Página 39

<!-- source-page: 39 -->

GNUFDL • PID_00214802                                                                                  39                                                                                                      La gestión de procesos



    void CreateChildProcess()

    // Create a child process that uses the previously created pipes for STDIN and STDOUT.
    {
      TCHAR szCmdline[]=TEXT("child");

      PROCESS_INFORMATION piProcInfo;
      STARTUPINFO siStartInfo;
      BOOL bSuccess = FALSE;


      // Set up members of the PROCESS_INFORMATION structure.

      ZeroMemory( &piProcInfo, sizeof(PROCESS_INFORMATION));


      // Set up members of the STARTUPINFO structure.

      // This structure specifies the STDIN and STDOUT handles for redirection.
      ZeroMemory( &siStartInfo, sizeof(STARTUPINFO));
      siStartInfo.cb = sizeof(STARTUPINFO);

      siStartInfo.hStdError = g_hChildStd_OUT_Wr;
      siStartInfo.hStdOutput = g_hChildStd_OUT_Wr;
      siStartInfo.hStdInput = g_hChildStd_IN_Rd;

      siStartInfo.dwFlags |= STARTF_USESTDHANDLES;


      // Create the child process.

      bSuccess = CreateProcess(NULL,
        szCmdline // command line
        NULL // process security attributes

        NULL // primary thread security attributes
        TRUE // handles are inherited
        0 // creation flags

        NULL // use parent's environment
        NULL // use parent's current directory

        &siStartInfo // STARTUPINFO pointer
        &piProcInfo); // receives PROCESS_INFORMATION


      // If an error occurs, exit the application.
      ¡if (! bSuccess)
        ErrorExit(TEXT("CreateProcess"));

      else
      {
        // Close handles to the child process and its primary thread.

        CloseHandle(piProcInfo.hProcess);
        CloseHandle(piProcInfo.hThread);
      }

    }


El código del hijo es:


    #include <windows.h>

## Página 40

<!-- source-page: 40 -->

GNUFDL • PID_00214802                                                                                  40                                                                                                      La gestión de procesos


    #include <stdio.h>


    #define BUFSIZE 4096


    int main(void)

    {
      CHAR chBuf[BUFSIZE];
      DWORD dwRead, dwWritten;

      HANDLE hStdin, hStdout;
      BOOL bSuccess;


      hStdout = GetStdHandle(STD_OUTPUT_HANDLE);
      hStdin = GetStdHandle(STD_INPUT_HANDLE);

      if (
         (hStdout == INVALID_HANDLE_VALUE) ||
         (hStdin == INVALID_HANDLE_VALUE)

         )
         ExitProcess(1);


      // Send something to this process's stdout using printf.
      printf("\n ** This is en message from the child process. ** \n");


      // This simple algorithm uses the existence of the pipes to control execution.
      // It relies on the pipe buffers to ensure that no data is lost.
      // Larger applications would use more advanced process control.


    for (;;)
      {

       // Read from standard input and stop on error or no data.
       bSuccess = ReadFile(hStdin, chBuf, BUFSIZE, &dwRead, NULL);


       ¡if (! bSuccess || dwRead == 0)
       break;


       // Write to standard output and stop on error.
       bSuccess = WriteFile(hStdout, chBuf, dwRead, &dwWritten, NULL);


       ¡if (! bSuccess)
        break;

      }
      return 0;
    }

## Página 41

<!-- source-page: 41 -->

GNUFDL • PID_00214802                                                                                  41                                                                                                      La gestión de procesos

Descargar Markdown originalEstudiar este apartado