0 / 0 / 0
Регистрация: 13.04.2016
Сообщений: 7
1

Родительский и дочерний процесс: почему запуск начинается сразу с дочернего процесса?

23.12.2016, 14:56. Показов 1250. Ответов 1
Метки нет (Все метки)

Студворк — интернет-сервис помощи студентам
Родительский процесс должен считать содержимое текстового файла и передать его дочернему процессу. Дочерний процесс в полученном тексте должен найти все строки, начинающиеся с символов комментария (//), возможно, после нескольких пробелов, и вернуть их обратно родительскому процессу, добавляя в начало каждой строки её номер и в конец — длину. Родительский процесс должен вывести получаемые строки на печать. Почему запуск начинается сразу с дочернего процесса.

Родительский процесс.
C
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
#include <windows.h> 
#include <tchar.h>
#include <stdio.h> 
#include <strsafe.h>
 
#define BUFSIZE 4096 
 
HANDLE g_hChildStd_IN_Rd = NULL;
HANDLE g_hChildStd_IN_Wr = NULL;
HANDLE g_hChildStd_OUT_Rd = NULL;
HANDLE g_hChildStd_OUT_Wr = NULL;
 
HANDLE g_hInputFile = NULL;
 
void CreateChildProcess(void);
void WriteToPipe(void);
void ReadFromPipe(void);
void ErrorExit(PTSTR);
 
int _tmain(int argc, TCHAR *argv[])
{
    SECURITY_ATTRIBUTES saAttr;
 
    printf("\n->Start of parent execution.\n");
 
    // Установить флаг bInheritHandle, чтобы pipe наследовался. 
 
    saAttr.nLength = sizeof(SECURITY_ATTRIBUTES);
    saAttr.bInheritHandle = TRUE;
    saAttr.lpSecurityDescriptor = NULL;
 
    // Создать pipe для дочернего процесса в stdout. 
 
    if (!CreatePipe(&g_hChildStd_OUT_Rd, &g_hChildStd_OUT_Wr, &saAttr, 0))
        ErrorExit(TEXT("StdoutRd CreatePipe"));
 
    // Убедитесь, что для чтение к pipe для STDOUT не передается по наследству.
 
    if (!SetHandleInformation(g_hChildStd_OUT_Rd, HANDLE_FLAG_INHERIT, 0))
        ErrorExit(TEXT("Stdout SetHandleInformation"));
 
    // Создать pipe для дочернего процесса STDIN. 
 
    if (!CreatePipe(&g_hChildStd_IN_Rd, &g_hChildStd_IN_Wr, &saAttr, 0))
        ErrorExit(TEXT("Stdin CreatePipe"));
 
    // Убедитесь, что для чтение к pipe для STDIN не передается по наследству. 
 
    if (!SetHandleInformation(g_hChildStd_IN_Wr, HANDLE_FLAG_INHERIT, 0))
        ErrorExit(TEXT("Stdin SetHandleInformation"));
 
    // Создаём дочерний. 
 
    CreateChildProcess();
 
    //Получаем дескриптор входного файла для родителей.
    // Этот пример предполагает, что обычный текстовый файлиспользует выходную строку для проверки потока данных. 
 
    if (argc == 1)
        ErrorExit(TEXT("Please specify an input file.\n"));
 
    g_hInputFile = CreateFile(
        argv[1],
        GENERIC_READ,
        0,
        NULL,
        OPEN_EXISTING,
        FILE_ATTRIBUTE_READONLY,
        NULL);
 
    if (g_hInputFile == INVALID_HANDLE_VALUE)
        ErrorExit(TEXT("CreateFile"));
 
    // Write to the pipe that is the standard input for a child process. 
    // Data is written to the pipe's buffers, so it is not necessary to wait
    // until the child process is running before writing data.
 
    WriteToPipe();
    printf("\n->Contents of %s written to child STDIN pipe.\n", argv[1]);
 
    // Read from pipe that is the standard output for child process. 
 
    printf("\n->Contents of child process STDOUT:\n\n", argv[1]);
    ReadFromPipe();
 
    printf("\n->End of parent execution.\n");
 
    // The remaining open handles are cleaned up when this process terminates. 
    // To avoid resource leaks in a larger application, close handles explicitly. 
 
    return 0;
}
 
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.
        // Some applications might keep these handles to monitor the status
        // of the child process, for example. 
 
        CloseHandle(piProcInfo.hProcess);
        CloseHandle(piProcInfo.hThread);
    }
}
 
void WriteToPipe(void)
 
// Read from a file and write its contents to the pipe for the child's STDIN.
// Stop when there is no more data. 
{
    DWORD dwRead, dwWritten;
    CHAR chBuf[BUFSIZE];
    BOOL bSuccess = FALSE;
 
    for (;;)
    {
        bSuccess = ReadFile(g_hInputFile, chBuf, BUFSIZE, &dwRead, NULL);
        if (!bSuccess || dwRead == 0) break;
 
        bSuccess = WriteFile(g_hChildStd_IN_Wr, chBuf, dwRead, &dwWritten, NULL);
        if (!bSuccess) break;
    }
 
    // Close the pipe handle so the child process stops reading. 
 
    if (!CloseHandle(g_hChildStd_IN_Wr))
        ErrorExit(TEXT("StdInWr CloseHandle"));
}
 
void ReadFromPipe(void)
 
// Read output from the child process's pipe for STDOUT
// and write to the parent process's pipe for STDOUT. 
// Stop when there is no more data. 
{
    DWORD dwRead, dwWritten;
    CHAR chBuf[BUFSIZE];
    BOOL bSuccess = FALSE;
    HANDLE hParentStdOut = GetStdHandle(STD_OUTPUT_HANDLE);
 
    for (;;)
    {
        bSuccess = ReadFile(g_hChildStd_OUT_Rd, chBuf, BUFSIZE, &dwRead, NULL);
        if (!bSuccess || dwRead == 0) break;
 
        bSuccess = WriteFile(hParentStdOut, chBuf,
            dwRead, &dwWritten, NULL);
        if (!bSuccess) break;
    }
}
 
void ErrorExit(PTSTR lpszFunction)
 
// Format a readable error message, display a message box, 
// and exit from the application.
{
    LPVOID lpMsgBuf;
    LPVOID lpDisplayBuf;
    DWORD dw = GetLastError();
 
    FormatMessage(
        FORMAT_MESSAGE_ALLOCATE_BUFFER |
        FORMAT_MESSAGE_FROM_SYSTEM |
        FORMAT_MESSAGE_IGNORE_INSERTS,
        NULL,
        dw,
        MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
        (LPTSTR)&lpMsgBuf,
        0, NULL);
 
    lpDisplayBuf = (LPVOID)LocalAlloc(LMEM_ZEROINIT,
        (lstrlen((LPCTSTR)lpMsgBuf) + lstrlen((LPCTSTR)lpszFunction) + 40)*sizeof(TCHAR));
    StringCchPrintf((LPTSTR)lpDisplayBuf,
        LocalSize(lpDisplayBuf) / sizeof(TCHAR),
        TEXT("%s failed with error %d: %s"),
        lpszFunction, dw, lpMsgBuf);
    MessageBox(NULL, (LPCTSTR)lpDisplayBuf, TEXT("Error"), MB_OK);
 
    LocalFree(lpMsgBuf);
    LocalFree(lpDisplayBuf);
    ExitProcess(1);
}
Дочерний
C
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
#include <windows.h>
#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 a 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 (int i = 0; i < 2; ++i)
    {
        // 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;
}
0
Programming
Эксперт
94731 / 64177 / 26122
Регистрация: 12.04.2006
Сообщений: 116,782
23.12.2016, 14:56
Ответы с готовыми решениями:

Есть процесс A и дочерний процесс B, который находит хэндл родительского процесса A. И этот хэндл в разных случаях РАЗНЫЙ! Почему?
Друзья! Вот код A.exe, суть которого просто стать родительским для B.exe и висеть в системе. ...

Родительский и дочерний процесс: процесс не переходит обратно к родителю
Здравствуйте знаю что тема уже была, но все же! создаю элементарную программу, пока просто 1...

Родительский и дочерний процесс
Для начала код. ProcessA#include &lt;windows.h&gt; #include &lt;iostream&gt; #include &lt;stdio.h&gt; int...

Передать несколько чисел из дочернего процесса в родительский
В интернете находится информация только о передаче строк через pipe(). Как передать несколько...

1
Модератор
Эксперт CЭксперт С++
5275 / 2362 / 342
Регистрация: 20.02.2013
Сообщений: 5,756
Записей в блоге: 20
23.12.2016, 19:11 2
 Комментарий модератора 
Roman_03, пожалуйста, прочитайте правила форума.
Особое внимание обратите на следующие пункты:

.
0
IT_Exp
Эксперт
87844 / 49110 / 22898
Регистрация: 17.06.2006
Сообщений: 92,604
23.12.2016, 19:11
Помогаю со студенческими работами здесь

При завершении дочернего процесса, завершается и родительский
#!/usr/local/bin/perl use strict; use FCGI; use POSIX qw(setsid WNOHANG); $SIG{CHLD} = sub {...

Почему дочерний div влияет на родительский?
Здравствуйте. &lt;div class=&quot;container&quot; id=&quot;scroll&quot;&gt; &lt;div class=&quot;banner&quot;&gt; &lt;div...

Запуск дочернего процесса
Почему второй вариант не запускает дочерний процесс? // Работает CreateProcess(L&quot;programma.exe&quot;,...

Запуск и остановка дочернего процесса
Здравствуйте, Есть у меня программа, где нечто выполняется в бесконечном цикле. Есть программа,...


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
2
Ответ Создать тему
Опции темы

КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2023, CyberForum.ru