这是我在c中执行矩阵乘法实现fork和共享内存的代码。看来我得到的价值主要是垃圾价值。也许我没有初始化数组C的值,它首先是结果数组。(我是C的初学者,这是我第一次使用共享内存)
#include <stdio.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/shm.h>
#include <sys/ipc.h>
#include <sys/stat.h>
#include <sys/wait.h>
#define N 3
void doMulT(int row,int col,int x ,int a[][N],int b[][N],int c[]);
int main()
{
int Ma[N][N];
int Mb[N][N];
int segment_id;
pid_t pid=-1;
printf("Input the elements in Matrix A (%dx%d) : \n",N,N);
for(int k = 0; k<N ;k++)
{
for(int d = 0; d<N ; d++)
{
scanf("%d",&Ma[k][d]);
}
}
printf("Input the elements in Matrix B (%dx%d) : \n",N,N);
for(int k = 0; k<N ;k++)
{
for(int d = 0; d<N ; d++)
{
scanf("%d",&Mb[k][d]);
}
}
segment_id = shmget(IPC_PRIVATE,1024, S_IRUSR|S_IWUSR);
int *C = (int*)shmat(segment_id,NULL,0);
for(int i=0;i<N*N;i++)
{
if(pid != 0)
{
pid = fork();
}
}
if(pid == 0)
{
for(int i = 0; i<N; i++)
{
for(int j =0; i<N; j++)
{
if(C[i*N+j]==0)
{
doMulT(i,j,N,Ma,Mb,C);
}
}
}
}
else
{
for(int k =0;k<N*N;k++)
{
wait(NULL);
}
printf("==========Result==========\n");
for(int i=0; i<N; i++)
{
for(int j=0; j<N; j++)
{
printf("%d",C[i*N+j]);
printf(" ");
}
printf("\n");
}
}
shmdt(C);
shmctl(segment_id, IPC_RMID, NULL);
}
void doMulT(int row,int col,int x ,int a[][N],int b[][N],int c[])
{
for(int k=0; k<x; k++)
{
c[row*x+col]+=a[row][k]*b[k][col];
}
}
输入的例子
Input the elements in Matrix A (3x3) :
1 1 1
2 2 2
3 3 3
Input the elements in Matrix B (3x3) :
1 1 1
2 2 2
3 3 3
输出就像
6 6 6
123482868 -745374 -2637821
456729394 -98475839 -2884829
该答案的第一部分旨在显示原始程序中的问题以及调试问题的方法。
我添加了一些printf
输出以查看流程将执行的操作
if(pid == 0)
{
for(int i = 0; i<N; i++)
{
for(int j =0; i<N; j++)
{
if(C[i*N+j]==0)
{
printf("process %ld calculating (%d, %d)\n", (long)getpid(), i, j);
doMulT(i,j,N,Ma,Mb,C);
}
}
}
}
并得到这样的输出:
process 747 calculating (0, 204)
process 746 calculating (0, 292)
process 746 calculating (0, 293)
process 747 calculating (0, 205)
process 746 calculating (0, 294)
process 747 calculating (0, 206)
process 746 calculating (0, 295)
process 747 calculating (0, 207)
这意味着for的循环j
是错误的。
有一个错字:
for(int j =0; i<N; j++)
必须是
for(int j =0; j<N; j++) // j<N instead of i<N
另外,我曾经memset
用0初始化共享内存。
修复循环后,我得到
process 238 calculating (0, 0)
process 238 calculating (0, 1)
process 238 calculating (0, 2)
process 238 calculating (1, 0)
process 238 calculating (1, 1)
process 238 calculating (1, 2)
process 238 calculating (2, 0)
process 238 calculating (2, 1)
process 238 calculating (2, 2)
==========Result==========
6 6 6
12 12 12
18 18 18
这意味着一个孩子在其他孩子变得活跃之前就完成了所有工作。
处理循环中的延迟为其他进程提供了一些工作的机会。
注意:这并不是真正的解决方案。主要目的是表明您不能依赖系统在流程之间分配工作。
它还显示矩阵乘法不是用于多处理的好用例,因为矩阵单元的计算(至少对于您的示例中的小矩阵而言)显然比创建新过程快得多。
if(pid == 0)
{
for(int i = 0; i<N; i++)
{
for(int j =0; j<N; j++)
{
if(C[i*N+j]==0)
{
printf("process %ld calculating (%d, %d)\n", (long)getpid(), i, j);
doMulT(i,j,N,Ma,Mb,C);
sleep(1); // give other processes a chance to do some work
}
}
}
}
为了获得良好的解决方案,您必须实现一种为每个子进程分配特定任务的方法。一种选择是将循环变量i
(或对于行和列可能使用两个单独的循环变量)传递给子进程中的处理函数,如以下版本所示。
#include <stdio.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/shm.h>
#include <sys/ipc.h>
#include <sys/stat.h>
#include <sys/wait.h>
#include <memory.h>
#include <errno.h>
#include <stdlib.h>
#define N 3
#define SIZE 1024
void doMulT(int row,int col,int x ,int a[][N],int b[][N],int c[]);
int main()
{
int Ma[N][N] = {
{1, 1, 1},
{2, 2, 2},
{3, 3, 3}
};
int Mb[N][N] = {
{1, 1, 1},
{2, 2, 2},
{3, 3, 3}
};
int segment_id;
pid_t pid=-1;
#if 0
printf("Input the elements in Matrix A (%dx%d) : \n",N,N);
for(int k = 0; k<N ;k++)
{
for(int d = 0; d<N ; d++)
{
scanf("%d",&Ma[k][d]);
}
}
printf("Input the elements in Matrix B (%dx%d) : \n",N,N);
for(int k = 0; k<N ;k++)
{
for(int d = 0; d<N ; d++)
{
scanf("%d",&Mb[k][d]);
}
}
#endif
segment_id = shmget(IPC_PRIVATE, SIZE, S_IRUSR|S_IWUSR);
int *C = (int*)shmat(segment_id,NULL,0);
memset(C, 0, SIZE);
for(int i=0; (pid != 0) && (i<N); i++)
{
for(int j=0; (pid != 0) && (j<N); j++)
{
if(pid != 0)
{
pid = fork();
if(pid == 0)
{
printf("process %ld calculating (%d, %d)\n", (long)getpid(), i, j);
doMulT(i,j,N,Ma,Mb,C);
exit(0);
}
}
}
}
if(pid != 0)
{
while(wait(NULL) != -1 || (errno != ECHILD))
{
;
}
printf("==========Result==========\n");
for(int i=0; i<N; i++)
{
for(int j=0; j<N; j++)
{
printf("%d",C[i*N+j]);
printf(" ");
}
printf("\n");
}
}
shmdt(C);
shmctl(segment_id, IPC_RMID, NULL);
}
void doMulT(int row,int col,int x ,int a[][N],int b[][N],int c[])
{
for(int k=0; k<x; k++)
{
c[row*x+col]+=a[row][k]*b[k][col];
}
}
输出如下:
process 7489 calculating (0, 0)
process 7495 calculating (2, 0)
process 7496 calculating (2, 1)
process 7497 calculating (2, 2)
process 7493 calculating (1, 1)
process 7490 calculating (0, 1)
process 7494 calculating (1, 2)
process 7492 calculating (1, 0)
process 7491 calculating (0, 2)
==========Result==========
6 6 6
12 12 12
18 18 18
本文收集自互联网,转载请注明来源。
如有侵权,请联系[email protected] 删除。
我来说两句