c-将整数数组分离成大致相等的块,通过Pipe发送给N个子级



父进程在子进程之间平均分配工作。从本质上讲,用户将输入
数据将具有的整数数量,并将其存储到计数中。然后将输入count个整数,最后一个输入将是父级必须将数据发送到的N个子级。我最终将使用子级对数据进行合并排序,但目前我能够使用printfs将数组分离为大致相等的块,在感觉良好之后,我将printf切换到了对要发送给孩子们的管道的write((调用。它不起作用,我不确定发生了什么,我尝试了很多不同的东西。任何帮助都会很棒!感谢

以下是我的代码输出示例:

Input count of integers, data, then N Children: 10
1 2 3 4 5 6 7 8 9 10 3
1 2 3 4 5 6 7 8 9 10 
I'm the parent --> 1111797
I'm child # 2 , with pid: 1112221
I'm child # 1 , with pid: 1112220
I'm child # 3 , with pid: 1112222
process 1111797 is sending data
1 2 3 4 5 6 7 8 9 10 child 1 recieved data
Child PID 1112220 terminated with return status 0 

通常,对于下面的代码,我会使用for循环迭代int l,而l小于N个子级,以便通过管道多维数组中每个子级的管道发送数据。。但在这种情况下,我只是做了l++,因为当代码将数据分离成N个(子级数量(单独的块时,已经考虑到了子级。问题代码:

//  seperates file into chunks
int l = 0;
for (start = 0, end = chunk_size; start < count; start = end, end = start + chunk_size)
{
if (bonus)
{
end++;
bonus--;
}
// l is the child process to send the pipe to

for (int o = start; o < end; o++)
{

if (write(fd[l][WRITE], &ar[o], sizeof(int)) < 0)
{
perror("writing to pipe");
exit(1);
}
}
l++;
}

主要代码:

#include <pthread.h>
#include <stdio.h>
#include <errno.h>
#include <unistd.h>
#include <stdlib.h>
#include <string.h>
#include <stdlib.h>
#include <errno.h>
#include <unistd.h>
#include <signal.h>
#include <sys/types.h>
#include <sys/wait.h>
#include <stdbool.h>
#define READ 0
#define WRITE 1
// counts the number of data
int count;
// counts number of children
int N = 0;
pid_t pid;
bool running = true;
int child_work(int child_num, int fd[], int arr[]);
void sigHandler(int number)
{
printf("process %d is sending datan", getpid());
}

int main()
{
signal(SIGUSR1, sigHandler);
// The parent process is required to maintain  input descriptors (the upstream pipes) and
// output descriptors (the downstream pipes).
int i = 0;
int *ar;
printf("Input count of integers, data, then N Children: ");
scanf("%d", &count);
ar = malloc(count * sizeof(int)); // alocates memory based on stdin input size on runtime
if (ar == NULL)
{
fprintf(stderr, "memory allocation failed.n");
return -1;
}
for (i = 0; i < count; i++)
{
scanf("%d", &ar[i]);
if (ar[i] > 103 || ar[i] < -10)
{
fprintf(stderr, "integer out of scope");
return -1;
}
}
// scan in the numbe of children
scanf("%d", &N);
printf("n");
int chunk_size = (count / N);
int bonus = count - (chunk_size * N);
int start;
int end;
// multi-dimensional array to initalize pipes for all children
int fd[N][2];
// prints initial array;
for (i = 0; i < count; i++)
{
printf("%d ", ar[i]);
}


printf("nn");
printf("I'm the parent --> %dn", getpid()); // prints parent id.
for (int fk = 0; fk < N; fk++)
{
// parent
// pipe call
if (pipe(fd[fk]) < 0)
{
perror("plumbing problem");
exit(1);
}
if ((pid = fork()) < 0)
{
perror("fork");
exit(1);
}
// child
if (pid == 0)
{
signal(SIGUSR1, SIG_IGN);
// sleep(4);
printf("I'm child # %d , with pid: %dn", fk + 1, getpid());
// testing with sleep calls
sleep(1);
child_work(fk, fd[fk], ar);
free(ar);
exit(0);
}
// parent
// printf("parent 1st stage, %dn", getpid());
}
// After the loop--parent code
// waits for USR1 Signal
pause();
//***signal handler triggered** send data to child via Pipe
// loop to close READ file descriptor for j child
for (int j = 0; j < N; j++)
{
if (close(fd[j][READ]) < 0)
{
perror("closing fd[READ]");
exit(1);
}
}
// loop to WRITE file descriptor for fk child
/* for (int l = 0; l < N; l++)
{
for (int q = 0; q < count; q++)
{
if (write(fd[l][WRITE], &ar[q], sizeof(int)) < 0)
{
perror("writing to pipe");
exit(1);
}
}
}
*/

//  seperates file into chunks
int l = 0;
for (start = 0, end = chunk_size; start < count; start = end, end = start + chunk_size)
{
if (bonus)
{
end++;
bonus--;
}
// l is the child process to send the pipe to

for (int o = start; o < end; o++)
{

if (write(fd[l][WRITE], &ar[o], sizeof(int)) < 0)
{
perror("writing to pipe");
exit(1);
}
}
l++;
}

/*
for (int l = 0; l < N; l++)
{
for (int q = 0; q < count; q++)
{
if (write(fd[l][WRITE], &ar[q], sizeof(int)) < 0)
{
perror("writing to pipe");
exit(1);
}
}
} */
int wstatus;
for (int wt = 0; wt < N; wt++)
{
pid = wait(&wstatus);
printf("Child PID %ld terminated with return status %d n", (long)pid, WEXITSTATUS(wstatus));
}
// printf("parent 3rd stage");

free(ar);
}
int child_work(int child_num, int fd[], int arr[])
{
if (close(fd[WRITE]) < 0)
{
perror("closing fd[WRITE]");
exit(1);
}
// loop to READ file descriptor for fk number of Data
for (int fk = 0; fk < count; fk++)
{
if (read(fd[READ], &arr[fk], sizeof(int)) < 0)
{
perror("reading to pipe");
exit(1);
}
printf("%d ", arr[fk]);
}
sleep(1);
printf("child %d recieved datan", child_num + 1);


return 0;
}

IMHO,您尝试的方法不对。你试图给每个孩子提供相同大小的信息块,当你需要为每个孩子提供一个已经有序的数字块时(这就是合并排序的工作方式(,你首先必须开始将你的输入分成块,并给每个孩子(或你有n个(一个完整的数字块(一个块是已经有序的数字的子集,例如1、2、5、3、7、4有三个块,{1、2,5}、{3、7}和{4}(。你这样做,然后让你的孩子返回他们拥有的数字,并在每个孩子的数字集中选择最低的数字,这将把N个区块合并为一个,当你只有一个区块时,这个过程就会终止。。。。(例如,你只给一个孩子块,因为只有一个块(

顺便说一句,上面的方法不需要多个线程,因为卡经销商只会把卡发给每个孩子。。。。而孩子们的任务只是存储数据,以将其以更大的块形式返回给经销商。最好是制作一个流程管道,每个流程进行一次迭代,每个流程以数组的形式处理卡片,然后将块合并到管道中的下一个流程。在这种情况下,所有迭代都是并行工作的,一旦开始向下一个进程输出卡片,下一个过程开始将它们处理成块并合并(实际上可以有一个过程处理卡片,第二个过程将它们合并并转发到下一步(一旦检测到一个新的块,就创建新的过程(如果你创建了与块一样多的过程,那么你只需一次迭代就可以完成(

最新更新