0
votes

So my task goes like this:

The program needs 2 processes in one main function

  • First process creates or opens a file "log.txt" which is in the same directory where the program is located. Then it adds user input to this file.
  • Second process is a "monitor" of this file. It checks if the file exists, shows its size and shows how many characters were entered since the second process started.

Note that I am aware that the program itself is a process, but it needs to be done like that. There are some "tips" to use a file as mutex (CreateFile parameters) that would be the dsShareMode with FILE_SHARE_DELETE | FILE_SHARE_READ | FILE_SHARE_WRITE parameter.

Now my question is: how do you create 2 processes to handle its own line of code? I've seen many examples of CreateProcess function but I don't really understand the first two parameters of this function

  • lpApplicationName and
  • lpCommandLine

What am I supposed to pass to it in order to run 2 processes, one to handle the user input and the other to be the "monitor"?

The first process is meant to handle those lines of code:

        std::string buffer;
        std::cout << "Enter your text:" << std::endl;
        getline(std::cin, buffer);
        HANDLE hFile = CreateFile("log.txt", FILE_APPEND_DATA, FILE_SHARE_DELETE | FILE_SHARE_READ | FILE_SHARE_WRITE, 0, OPEN_ALWAYS, FILE_ATTRIBUTE_NORMAL, 0);
        DWORD written = 0;
        WriteFile(hFile, buffer.c_str(), buffer.size(), &written, NULL);

While the second process should only care about this:

hFile = CreateFile("log.txt", FILE_READ_ATTRIBUTES, FILE_SHARE_DELETE | FILE_SHARE_READ | FILE_SHARE_WRITE, 0, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, 0);
        if (hFile == INVALID_HANDLE_VALUE)
        {
            std::cout << "CreateFile error " << GetLastError() << std::endl;
        }
        else
        {
            DWORD size = GetFileSize(hFile, NULL);
            std::cout << "\nCurrent file size: " << size << std::endl;
            CloseHandle(hFile);
        }

        int stringLength = 0;
        for(int i=0; buffer[i]; i++)
            stringLength++;

            std::cout << "\nCharacters given since last startup: " << stringLength << std::endl;
3
Does it have to be two processes? Using two threads seems more natural given the problem described. - john
Yes, the task has to use 2 processes. But as I pointed out, the first two parameters of the CreateProcess functions are the thing I don't really understand. - KAER
Option the first: have two separate executables. Option the second: have one executable but pass commandline option to specify which mode it should run as. Note that this solution is very unidiomatic; normally one would use threads as @john said. - Botje
Did you read the documentation and the example it links to? - Botje

3 Answers

1
votes

Assuming you have a separate helper.exe, you can do:

CreateProcess(nullptr, "helper logger-mode", ...)

and

CreateProcess(nullptr, "helper monitor-mode", ...)

This will create two processes that see either logger-mode or monitor-mode in their second argument (argv[1]).

0
votes

The question appears to demand having the same program being run as two separate processes. If that is the case, the program will need to handle command line arguments and tailor its functionality accordingly.

0
votes

@Botje I've managed to do something like that. Could you take a look at tell me if such solution is acceptable?

int main(int argc, char *argv[])
{
std::string cmdline1 = "main Proc1";
std::string cmdline2 = "main Proc2";
std::string buffer;
HANDLE hFile;

    STARTUPINFO si;
    PROCESS_INFORMATION pi;

    ZeroMemory(&si, sizeof(si));
    ZeroMemory(&pi, sizeof(pi));

    si.cb = sizeof(si);
    CreateProcess(argv[0], const_cast<char *>(cmdline1.c_str()), NULL, NULL, FALSE, CREATE_NEW_CONSOLE, NULL, NULL, &si, &pi);
    CreateProcess(argv[0], const_cast<char *>(cmdline2.c_str()), NULL, NULL, FALSE, CREATE_NEW_CONSOLE, NULL, NULL, &si, &pi);

if(strcmp(argv[1], "Proc1"))
{
    while(1)
    {
        std::cout << "Enter your text:" << std::endl;
        getline(std::cin, buffer);
        hFile = CreateFile("log.txt", FILE_APPEND_DATA, FILE_SHARE_DELETE | FILE_SHARE_READ | FILE_SHARE_WRITE, 0, OPEN_ALWAYS, FILE_ATTRIBUTE_NORMAL, 0);
        DWORD written = 0;
        WriteFile(hFile, buffer.c_str(), buffer.size(), &written, NULL);
    }
}

if(strcmp(argv[1], "Proc2"))
{
    DWORD charactersGiven = 0;
    while(1)
    {
        hFile = CreateFile("log.txt", GENERIC_READ, FILE_SHARE_DELETE | FILE_SHARE_READ | FILE_SHARE_WRITE, 0, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, 0);
            if (hFile == INVALID_HANDLE_VALUE)
            {
                std::cout << "CreateFile error " << GetLastError() << std::endl;
            }
            else
            {
                DWORD size = GetFileSize(hFile, NULL);
                std::cout << "\nCurrent file size: " << size << std::endl;
                if(charactersGiven == 0)
                charactersGiven = size;

                std::cout << "Characters given since last startup: " << size - charactersGiven << std::endl;
            }
            Sleep(4000);
        }
}
return 0;
}