C分叉的问题,错误的结果,可能是共享内存

C分叉的问题,错误的结果,可能是共享内存,c,fork,shared-memory,C,Fork,Shared Memory,我有一个任务,使用共享内存执行带叉的矩阵乘法,然后将时间结果与不带叉的乘法进行比较,因此这里是不带叉的乘法: int matrizA[Am][An]; int matrizB[An][Bp]; //here i fill the matrix from a .txt file int matrizR[Am][Bp]; int a,b,c; for (a=0; a < Am; a++){ for (b = 0; b < Bp; b++) { matr

我有一个任务,使用共享内存执行带叉的矩阵乘法,然后将时间结果与不带叉的乘法进行比较,因此这里是不带叉的乘法:

int matrizA[Am][An];
int matrizB[An][Bp];

//here i fill the matrix from a .txt file

int matrizR[Am][Bp];
int a,b,c;
for (a=0; a < Am; a++){
    for (b = 0; b < Bp; b++)
    {
        matrizR[a][b] = 0;
        for (c=0; c<An; c++){
            matrizR[a][b] += matrizA[a][c] * matrizB[c][b]; 
        }
    }
}
int matrizA[Am][An];
int matrizB[An][Bp];
//在这里,我从一个.txt文件填充矩阵
int matrizR[Am][Bp];
INTA、b、c;
对于(a=0;a对于(c=0;c而言,由于这是一项家庭作业,因此未给出完整的解决方案,但您用于在Unix上获取共享内存的函数在此处有文档记录:

您可以调用
shmget()
,然后在每个子进程中将提供给您的标识符传递给
shmat()
,以获取指向共享内存的指针

一种方法是让每个进程在管道中传回其结果,并复制它们,但这会慢得多。另一种方法是使用线程而不是进程,因为线程共享内存。另一种方法是传递消息。另一种方法是内存映射文件。但将共享内存转换为指向结构的指针是最简单的方法,而且有最好的表现


最后,如果要写入同一共享内存,则需要小心不要让两个进程写入同一内存。如果每行打开一个进程,并且行正确对齐,则不应出现问题,但安全的方法是使用锁或原子变量。

当您分叉一个新进程时,实际上创建一个新的进程,任何进程的内存都是独立于任何其他进程的。因此,是的,您需要共享内存,或者您可以使用线程。在这个示例中,看到我如何实现共享内存了吗?我读了这个示例,但trully不理解它@Stas的必要性,所以像这个示例一样,我的示例中的glob_var应该是所有的矩阵?我该怎么做呢优化它们?是否要求您必须使用进程和共享内存?否则线程就容易多了。您确定使用管道比共享内存慢得多吗?假设每个子进程处理一行,二进制将其写入管道(每个子进程一个管道),而父进程只是整理它从管道中读取的内容。它应该更难写,但不确定时间。但我很确定它会比在每次写入变量时使用共享内存和全局锁更快(无论如何,向上投票:-).但正如@lorehead所说,我不应该使用锁,因为每个进程都会写入数组的不同部分,所以不会有两个进程写入同一内存空间,对吗?原子变量不应该在每次写入时都需要全局锁。事实上,如果数组中没有任何进程的部分与其他任何进程共享缓存线所有的进程都应该能够在没有开销的情况下写入它们的部分。我想,你也可以为每个对象使用一个不同的共享内存块。但是要回答你的问题:考虑每个数组中有多少个副本需要在管道上传输。这里有一种哈希解决方案。ds必须处理任何原子内容:将行声明为指向行向量的指针数组,然后将每个行初始化为只有一个子进程将打开的共享内存段。在现实世界中,这不是一个很好的解决方案,因为没有缓存一致性和大量开销,但它保持了每个人都可以使用的内存块他以透明的方式完全分开了。
int matrizR2[Am][Bp];
pid_t pids[Am][Bp];
int h,j;

/* Start children. */TY
for (h = 0; h < Am; ++h) {
    for (j=0; j<Bp ; ++j){
      if ((pids[h][j] = fork()) < 0) {
        perror("fork");
        abort();
      } else if (pids[h][j] == 0) {
        matrizR2[h][j] = 0;
        for (c=0; c<An; c++){
            matrizR2[h][j] += matrizA[h][c] * matrizB[c][j]; 
        }
        printf("im fork %d,%d\n",h,j);
        exit(0);
      }
    }
}
/* Wait for children to exit. */
int status;
pid_t pid;
while (n > 0) {
  pid = wait(&status);
  --n; 
}