我有一个整数数组,我必须确定哪些索引可以使用P进程找到给定值。我拆分向量,以便每个进程可以在子向量中搜索该值,并在管道上写入索引。一个进程可以在多个位置找到该值,并且我使用一个简单的链表来存储每个进程的索引。在那之后我写在管道上。我的问题是读数是偏的,我得到了分段错误,因为列表的大小比我声明的要大。我该怎么做呢?
struct Node;
typedef struct Node{
int val;
struct Node *next;
}Node;
static int elementsList[] = { 1,2,3,4,5,6,7,8,3,10,11,12,3,14,15,16,17,
1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,
1,2,3,4,5,6,7,8,9,3,11,12,13,14,3,16,17,
1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,
1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,3 };
//method called by a process to check for the value in a subvector
void getPosition(int elemList[],int start,int step, int size, int value,int wPipe ){
Node *first = NULL;
Node *current;
Node *temp;
int i;
for(i = start; i < size ; i += step){
if(value == elemList[i]){
current = (Node*) malloc (sizeof(Node));
current->val = i;
if(first == NULL){
first = current;
first->next = NULL;
}else{
temp = first;
while(temp->next != NULL){
temp = temp->next;
}
current->next = NULL;
temp->next = current;
}
}
}
write(wPipe,&first,sizeof(Node) );
}
int main(){
//fork() the P processes
for(child = 0; child < P ; child++){
if((pid[child] = fork()) < 0){
perror("fork");
exit(1);
}
else if(pid[child] == 0){
close(fd[0]);
printf("Child #%d\n",getpid());
//call getPositions(...) method
getPosition(elementsList,child,P,SIZE,valueToFind,fd[1]);
close(fd[1]);
exit(0);
}
}
//read form the pipe and print the positions
Node *temp = NULL;
for(child = 0; child < P; child++){
temp = (Node*) malloc(sizeof(Node));
nbytes = read(fd[0],&temp, sizeof(Node));
while(temp != NULL){
printf("Position: %d\n",temp->val);
temp = temp->next;
}
}
}
答案 0 :(得分:3)
一旦进程独立工作,他们就可以使用相同的地址用于不同的目的。基本上,除非数据位于两个进程中映射到同一地址的共享内存中,否则不要在进程之间传递地址。您需要将整数索引(仅)写入管道,并从管道中读取它们。
这大大简化了您需要的代码:
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
static int elementsList[] =
{
1, 2, 3, 4, 5, 6, 7, 8, 3, 10, 11, 12, 3, 14, 15, 16, 17,
1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17,
1, 2, 3, 4, 5, 6, 7, 8, 9, 3, 11, 12, 13, 14, 3, 16, 17,
1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17,
1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 3
};
enum { SIZE = sizeof(elementsList)/sizeof(elementsList[0]) };
// method called by a process to check for the value in a subvector
static void getPosition(int elemList[], int start, int step, int size, int value, int wPipe)
{
for (int i = start; i < size; i += step)
{
if (value == elemList[i])
write(wPipe, &i, sizeof(i));
}
}
int main(void)
{
enum { P = 5 };
pid_t pid[P];
int fd[2];
int valueToFind = 3;
pipe(fd);
for (int child = 0; child < P; child++)
{
if ((pid[child] = fork()) < 0)
{
perror("fork");
exit(1);
}
else if (pid[child] == 0)
{
close(fd[0]);
printf("Child #%d\n", getpid());
getPosition(elementsList, child, P, SIZE, valueToFind, fd[1]);
close(fd[1]);
exit(0);
}
}
// read from the pipe and print the positions
close(fd[1]);
int index;
int n = 0;
printf("Seeking: %d\n", valueToFind);
while (read(fd[0], &index, sizeof(index)) == sizeof(index))
printf("%2d: Position: %2d (%d)\n", ++n, index, elementsList[index]);
return 0;
}
请注意,父进程在进入循环之前关闭管道的写入端是至关重要的。
示例输出:
Child #55829
Child #55830
Child #55831
Child #55832
Child #55833
Seeking: 3
1: Position: 70 (3)
2: Position: 36 (3)
3: Position: 2 (3)
4: Position: 12 (3)
5: Position: 8 (3)
6: Position: 43 (3)
7: Position: 48 (3)
8: Position: 53 (3)
9: Position: 19 (3)
10: Position: 84 (3)