[英]How to send data from multiple child process to a parent array using pipe or any other method?
我正在嘗試通過fork()
創建多個進程,並對子進程進行一些數學運算,例如數組元素的總和,然后將值返回給父進程,父進程會將每個值保存在parentArray
中,如代碼中所述。 現在我的問題是如何在這個階段執行此操作,我只收到第一個進程的一個值,rest 的值為零。 是否有另一種傳遞值的方法,或者可以通過 pipe 來完成? 請幫我
#include <unistd.h>
#include <stdlib.h>
#include <time.h>
#include <sys/types.h>
#include <sys/wait.h>
void showReturnStatus(pid_t childpid,int status){
if (WIFEXITED(status) && !WEXITSTATUS(status))
printf("Child %ld terminated normally\n", (long)childpid);
else if (WIFEXITED(status))
printf("Child %ld terminated with return status %d\n",(long)childpid, WEXITSTATUS(status));
else if (WIFSIGNALED(status))
printf("Child %ld terminated due to uncaught signal %d\n",(long)childpid, WTERMSIG(status));
else if (WIFSTOPPED(status))
printf("Child %ld stopped due to signal %d\n",(long)childpid, WSTOPSIG(status));
}
int main(int argc, char *argv[])
{
srand(time(0));
int arraySize=9,noProcess=3,array[arraySize],status=0;
pid_t pid;
int parentSum=0;
int parentArray[3],fd[2]; //fd file descriptor
if(pipe(fd)==-1)
return 0;
for(int i=0 ;i<arraySize;i++)
array[i]=(rand()%100)+1;
for(int i=0;i<arraySize;i++){
printf("\n %d : %d ",i,array[i]);
}
printf("\nParent PID[%d] \n",getpid());
for(int childP=0;childP<noProcess;childP++){
int child=fork();
int childSum;
if(child==0){
close(fd[0]);
childSum=0.0;
for(int i=childP*3;i<(childP+1)*3;i++)
childSum+=array[i];
printf("\nChild Process No [%d] PID [%d] Return Sum : %d \n",childP,getpid(),childSum);
write(fd[1],&childSum,sizeof(childSum));
close(fd[1]);
exit(0);
}
pid=wait(&status);
showReturnStatus(pid,status);
close(fd[1]);
read(fd[0],parentArray,sizeof(parentArray));
close(fd[0]);
}
for (int i=0;i<3;i++)
{
printf("\nValue Array : %d\n",parentArray[i]);
}
printf("\nParent Process with PID [%d] calculate Sum : %d\n",getppid());
return 0;
}
這是您的代碼的修訂版本,其中包含多項更改。
它允許子進程同時運行。
它關注各種錯誤情況。
它每行打印 10 個數據條目。
它檢查數組大小是進程數的 integer 倍數。
它不會在父節點中過早關閉 pipe。
它將錯誤報告給標准錯誤,並以失敗狀態退出。
它在 output 消息的末尾打印換行符; 它不需要在消息的開頭打印換行符。
我更喜歡避免noProcess
,因為它暗示“沒有進程”; 我將其重命名為numProcess
。
該代碼使用numProcess
和arraySize
來控制所有相關的循環等。
它在父進程中計算並打印總和,以便可以快速檢查來自子進程的值。 這也表明,出於本練習的目的,使用流程是一種人工制品。
它打印每行具有多個條目的數組。
我調整了計算以生成數字 1..99,以便格式%2d
統一工作。
我使用這些選項進行編譯(源代碼pipe79.c
,程序pipe79
):
gcc -O3 -g -std=c11 -Wall -Wextra -Werror -Wmissing-prototypes -Wstrict-prototypes pipe79.c -o pipe79
argc > 0
的測試只是為了確保使用了argc
——如果不是,代碼由於未使用的變量而無法編譯。
我介紹了變量numPerProcess
和start
和stop
,因為這些值至少使用了兩次。
除了制作 static 之外,我不需要觸摸showReturnStatus()
,由於我使用的編譯選項,這也是必要的。 function 不在此源文件之外使用,因此 IMO 無論如何它應該是static
。 如果它在其他地方使用,它將在 header 中聲明,該 header 將包含在它的定義位置和使用位置。
可能還有其他可以指出的詳細更改,但我忘記了我進行了更改。
代碼:
#include <assert.h>
#include <stdio.h>
#include <stdlib.h>
#include <sys/wait.h>
#include <time.h>
#include <unistd.h>
static void showReturnStatus(pid_t childpid, int status)
{
if (WIFEXITED(status) && !WEXITSTATUS(status))
printf("Child %ld terminated normally\n", (long)childpid);
else if (WIFEXITED(status))
printf("Child %ld terminated with return status %d\n", (long)childpid, WEXITSTATUS(status));
else if (WIFSIGNALED(status))
printf("Child %ld terminated due to uncaught signal %d\n", (long)childpid, WTERMSIG(status));
else if (WIFSTOPPED(status))
printf("Child %ld stopped due to signal %d\n", (long)childpid, WSTOPSIG(status));
}
int main(int argc, char *argv[])
{
srand(time(0));
int arraySize = 72;
int numProcess = 6;
int array[arraySize];
int fd[2];
const char *arg0 = (argc == 0) ? "pipe79" : argv[0]; /* Use argc */
assert(arraySize % numProcess == 0);
int numPerProcess = arraySize / numProcess;
if (pipe(fd) == -1)
{
fprintf(stderr, "%s: failed to create a pipe\n", arg0);
exit(EXIT_FAILURE);
}
int sum = 0;
for (int i = 0; i < arraySize; i++)
{
array[i] = (rand() % 99) + 1;
sum += array[i];
}
int width = 0;
const char *pad = "";
for (int i = 0; i < arraySize; i++)
{
width += printf("%s%2d: %2d", pad, i, array[i]);
pad = ", ";
if (width > 72)
{
putchar('\n');
width = 0;
pad = "";
}
}
if (width > 0)
putchar('\n');
printf("Sum calculated by parent: %d\n", sum);
printf("Parent PID[%d]\n", getpid());
for (int childP = 0; childP < numProcess; childP++)
{
int child = fork();
if (child < 0)
{
fprintf(stderr, "%s: failed to fork child %d\n", arg0, childP + 1);
exit(EXIT_FAILURE);
}
if (child == 0)
{
close(fd[0]);
int childSum = 0;
int start = childP * numPerProcess;
int stop = start + numPerProcess;
printf("Child PID %d: processing rows %d..%d\n", getpid(), start, stop - 1);
for (int i = start; i < stop; i++)
childSum += array[i];
printf("Child Process No [%d] PID [%d] Return Sum : %d\n", childP, getpid(), childSum);
if (write(fd[1], &childSum, sizeof(childSum)) != sizeof(childSum))
{
fprintf(stderr, "Child Process No [%d] PID [%d] failed to write to the pipe\n",
childP, getpid());
exit(EXIT_FAILURE);
}
close(fd[1]);
exit(0);
}
}
close(fd[1]);
sum = 0;
pid_t pid;
int status = 0;
while ((pid = wait(&status)) != -1)
{
int number;
showReturnStatus(pid, status);
if (read(fd[0], &number, sizeof(number)) != sizeof(number))
{
fprintf(stderr, "%s: parent process got a short read on the pipe\n", arg0);
exit(EXIT_FAILURE);
}
printf("sum from pipe: %d\n", number);
sum += number;
}
printf("Parent Process with PID [%d] accumulated sum : %d\n", getpid(), sum);
return 0;
}
樣品 output:
0: 68, 1: 13, 2: 74, 3: 37, 4: 88, 5: 4, 6: 73, 7: 94, 8: 2, 9: 71
10: 20, 11: 19, 12: 93, 13: 96, 14: 13, 15: 96, 16: 98, 17: 12, 18: 94, 19: 10
20: 27, 21: 38, 22: 48, 23: 14, 24: 18, 25: 50, 26: 61, 27: 15, 28: 88, 29: 41
30: 2, 31: 99, 32: 42, 33: 8, 34: 55, 35: 32, 36: 29, 37: 53, 38: 78, 39: 15
40: 69, 41: 19, 42: 85, 43: 78, 44: 3, 45: 59, 46: 96, 47: 37, 48: 35, 49: 95
50: 59, 51: 12, 52: 63, 53: 34, 54: 31, 55: 17, 56: 88, 57: 63, 58: 74, 59: 15
60: 10, 61: 38, 62: 24, 63: 27, 64: 70, 65: 64, 66: 40, 67: 43, 68: 87, 69: 82
70: 35, 71: 11
Sum calculated by parent: 3451
Parent PID[58056]
Child PID 58057: processing rows 0..11
Child Process No [0] PID [58057] Return Sum : 563
Child PID 58058: processing rows 12..23
Child Process No [1] PID [58058] Return Sum : 639
Child PID 58059: processing rows 24..35
Child Process No [2] PID [58059] Return Sum : 511
Child PID 58060: processing rows 36..47
Child Process No [3] PID [58060] Return Sum : 621
Child PID 58061: processing rows 48..59
Child Process No [4] PID [58061] Return Sum : 586
Child 58059 terminated normally
sum from pipe: 563
Child 58060 terminated normally
sum from pipe: 639
Child 58058 terminated normally
sum from pipe: 511
Child 58057 terminated normally
sum from pipe: 621
Child 58061 terminated normally
sum from pipe: 586
Child PID 58062: processing rows 60..71
Child Process No [5] PID [58062] Return Sum : 531
Child 58062 terminated normally
sum from pipe: 531
Parent Process with PID [58056] accumulated sum : 3451
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.