简体   繁体   中英

How do I get each child process to output a string?

For my assignment, I'm expected to "have the children generate a, b, c, & time it and then have them generate multiples of each letter to see concurrency in action. Use nested loops to go up to, say 500 of each letter."

Currently, my letter_generator.exe program just randomly chooses a letter and prints said letter. My program (mostly my professor's I just added a few things) below creates 1500 child processes which isn't at all what I believe the assignment wants me to do. So, my question is how do I get each child process to print a specific letter?

#include <windows.h>
#include <iostream>
#include <ctime>
#include <chrono>
using namespace std;

int main(VOID){
  STARTUPINFO si;
  PROCESS_INFORMATION pi;

  // allocate memory
  ZeroMemory(&si, sizeof(si));
  si.cb = sizeof(si);
  ZeroMemory(&pi, sizeof(pi));
  
  volatile int i = 0;
  auto start = chrono::steady_clock::now();

  int const CHILD_PROCESS_LIMIT = 1500;
  for (i = 0; i < CHILD_PROCESS_LIMIT; i++){
      // create child process
    if (!CreateProcess(NULL, // use command line
      "C:\\Users\\Coughing\\Desktop\\letter_generator.exe", // app name
      NULL,  // don't inherit process handle
      NULL,  // don't inherit thread handle
      FALSE, // disable handle inheritance
      0,     // no creation flags
      NULL,  // use parent's environment block
      NULL,  // use parent's existing directory
      &si,
      &pi)){
        fprintf(stderr, "create process failed");
        return -1;
      }
  } 

  // parent waits for child to complete
  WaitForSingleObject(pi.hProcess, INFINITE);
  
  auto end = chrono::steady_clock::now();
  chrono::duration<double> elapsed_seconds = end - start;

  cout << "Children Complete in " << elapsed_seconds.count() << " seconds!";

  // close handles
  CloseHandle(pi.hProcess);
  CloseHandle(pi.hThread);
}

Below is a basic example of starting a child process and passing it an argument via the command line.

I'll leave the remainder of your homework for you to figure out.

Also note I'm using some C++17 features here, so if you can't compile either set the language standard in Visual Studio to C++17 or change the code to compile for the version of standard you're using.

Parent Process

#include <iostream>
#include <string>
#include <chrono>
#include <Windows.h>

int main( )
{
    std::cout << "Opening processes\n";

    for( int i = 0; i < 10; i++ ) 
    {
        STARTUPINFO startup_info{ };
        PROCESS_INFORMATION process_info{ };

        // To pass arguments to the child process replace 'test'
        // with whatever argument you want to pass.
        std::wstring args{ L"Child.exe test" };

        // create child process
        if( !CreateProcessW( 
            LR"(C:\Path\Child.exe)", // use command line
            args.data( ),
            nullptr,  // don't inherit process handle
            nullptr,  // don't inherit thread handle
            false,    // disable handle inheritance
            0,        // no creation flags
            nullptr,  // use parent's environment block
            nullptr,  // use parent's existing directory
            &startup_info,
            &process_info ) ) 
        {
            std::error_code ec{ static_cast<int>( 
                GetLastError( ) ), std::system_category( ) };

            std::cerr << "Failed to start process: " << ec.message( ) << '\n';
            return -1;
        }

        std::cout << "Waiting for process to complete\n";

        auto start{ std::chrono::high_resolution_clock::now( ) };

        if( auto code{ WaitForSingleObject( 
            process_info.hProcess, INFINITE ) }; code != WAIT_OBJECT_0 )
        {
            std::error_code ec{ static_cast<int>(
                GetLastError( ) ), std::system_category( ) };

            std::cerr << "Failed to wait for process: " << ec.message( ) << '\n';
        }

        auto elapsed{ std::chrono::high_resolution_clock::now( ) - start };
        auto duration{ std::chrono::duration_cast<std::chrono::microseconds>( elapsed ) };

        std::cout << "Time: " << duration.count( ) << " us\n";

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

Child Process

#include <iostream>

int main( int argc, char* argv[ ] )
{
    if( argc > 1 )
    {
        // The argument we passed will be located at index
        // 1 in argv.
        auto arg{ argv[ 1 ] };
        // Prints 'test'.
        std::cout << "Argument: " << arg << '\n';
    }
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM