我写了这段代码:
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#include <sys/types.h>
#include <sys/shm.h>
#define N 512
void chunk0(unsigned int *s, unsigned int *a, unsigned int *b, int MID,int it);
void chunk1(unsigned int *s, unsigned int *a, unsigned int *b, int MID,int it);
void chunk2(unsigned int *s, unsigned int *a, unsigned int *b, int MID,int it);
void chunk3(unsigned int *s, unsigned int *a, unsigned int *b, int MID,int it);
double get_time(void);
void main(void)
{
int i,j,k,iterations=0;
int plc=N/4;
unsigned int *a=(unsigned int *)malloc(N*N*(sizeof(unsigned int)));
unsigned int *b=(unsigned int *)malloc(N*N*(sizeof(unsigned int)));
unsigned int shmsz=N*N*(sizeof(unsigned int));
pid_t pid;
srand ( time(NULL) );
double start=get_time();
int shmid;
if ((shmid = shmget(IPC_PRIVATE, shmsz, IPC_CREAT | 0666)) < 0) {
perror("shmget");
exit(1);
}
//Now we attach the segment to our data space.
char *shm;
if ((shm = shmat(shmid, NULL, 0)) == (char *) -1) {
perror("shmat");
exit(1);
}
unsigned int *s = (unsigned int *) shm;
for(iterations=0;iterations<1000;iterations++){
printf("Iteration #%d\n",iterations+1);
for(i=0;i<N;i++){
for(j=0;j<N;j++){
*(a+(i*N+j))=(rand()%1001);
*(b+(i*N+j))=(rand()%1001);;
*(s+(i*N+j))=0;
}
}
pid = fork();
if (pid == 0) {
chunk0(s,a,b,plc,iterations);
break;
}else {
pid = fork();
if (pid == 0){
chunk1(s,a,b,plc,iterations);
break;
}else {
pid = fork();
if (pid == 0){
chunk2(s,a,b,plc,iterations);
break;
}else {
chunk3(s,a,b,plc,iterations);
wait(NULL);
}
}
}
wait(NULL);
}
double end=get_time();
double diff=end-start;
printf("\n Time for run this code is: %lf seconds \n",diff);
}
void chunk0(unsigned int *s, unsigned int *a, unsigned int *b, int MID,int it)
{
int i,j,k;
for(i=0;i<MID;i++){
for(j=0;j<N;j++){
for(k=0;k<N;k++){
*(s+(i*N+j))=*(s+(i*N+j))+(*(a+(i*N+k)))*(*(b+(k*N+j)));
}
}
}
printf("\tChild process 0 (Iteration %d) is done ***\n",it);
exit(0);
}
void chunk1(unsigned int *s, unsigned int *a, unsigned int *b, int MID,int it)
{
int i,j,k;
for(i=MID;i<MID*2;i++){
for(j=0;j<N;j++){
for(k=0;k<N;k++){
*(s+(i*N+j))=*(s+(i*N+j))+(*(a+(i*N+k)))*(*(b+(k*N+j)));
}
}
}
printf("\tChild process 1 (Iteration %d) is done ***\n",it);
exit(0);
}
void chunk2(unsigned int *s, unsigned int *a, unsigned int *b, int MID,int it)
{
int i,j,k;
for(i=MID*2;i<MID*3;i++){
for(j=0;j<N;j++){
for(k=0;k<N;k++){
*(s+(i*N+j))=*(s+(i*N+j))+(*(a+(i*N+k)))*(*(b+(k*N+j)));
}
}
}
printf("\tChild process 2 (Iteration %d) is done ***\n",it);
exit(0);
}
void chunk3(unsigned int *s, unsigned int *a, unsigned int *b, int MID,int it)
{
int i,j,k;
for(i=MID*3;i<N;i++){
for(j=0;j<N;j++){
for(k=0;k<N;k++){
*(s+(i*N+j))=*(s+(i*N+j))+(*(a+(i*N+k)))*(*(b+(k*N+j)));
}
}
}
printf("\tChild process 3 (Iteration %d) is done ***\n",it);
// exit(0);
}
double get_time(void){
struct timeval stime;
gettimeofday (&stime, (struct timezone*)0);
return (stime.tv_sec+((double)stime.tv_usec)/1000000);
}
程序不会等到一次迭代完成并开始下一次迭代! 看结果:
Iteration #1
Child process 0 (Iteration 0) is done ***
Child process 3 (Iteration 0) is done ***
Child process 1 (Iteration 0) is done ***
Iteration #2
Child process 2 (Iteration 0) is done ***
Child process 0 (Iteration 1) is done ***
Child process 1 (Iteration 1) is done ***
Child process 3 (Iteration 1) is done ***
Iteration #3
Child process 2 (Iteration 1) is done ***
Child process 0 (Iteration 2) is done ***
Child process 3 (Iteration 2) is done ***
Iteration #4
Child process 1 (Iteration 2) is done ***
Child process 2 (Iteration 2) is done ***
Child process 1 (Iteration 3) is done ***
Child process 3 (Iteration 3) is done ***
Iteration #5
Child process 0 (Iteration 3) is done ***
Child process 2 (Iteration 3) is done ***
Child process 0 (Iteration 4) is done ***
Child process 1 (Iteration 4) is done ***
Child process 2 (Iteration 4) is done ***
Child process 3 (Iteration 4) is done ***
Iteration #6
Child process 1 (Iteration 5) is done ***
Child process 0 (Iteration 5) is done ***
Child process 2 (Iteration 5) is done ***
Child process 3 (Iteration 5) is done ***
Iteration #7
Child process 0 (Iteration 6) is done ***
Child process 1 (Iteration 6) is done ***
Child process 2 (Iteration 6) is done ***
Child process 3 (Iteration 6) is done ***
这个怎么样?
我用了wait(NULL)但是......
答案 0 :(得分:7)
wait()
只会等到单个子进程退出。你想等到他们都退出了。我想你只需要连续三次打电话......
答案 1 :(得分:1)
您没有正确等待创建的子进程。你应该这样做:
pid = fork();
if (pid == 0) {
chunk0(s,a,b,plc,iterations);
break;
}else {
pid = fork();
if (pid == 0){
chunk1(s,a,b,plc,iterations);
break;
}else {
pid = fork();
if (pid == 0){
chunk2(s,a,b,plc,iterations);
break;
}else {
chunk3(s,a,b,plc,iterations);
wait(NULL);
}
wait(NULL);
}
wait(NULL);
}
它看起来很糟糕,你应该重新考虑你的程序逻辑,使它更具可读性。另外,请记住在退出之前从子进程中正确清理资源(请参阅shmdt)。
要考虑的另一件事是使用shm_open和shm_unlink代替。