在我的课堂上,我们目前正在学习并行处理。我们正在用C编写并使用Linux命令行。
在我们的练习中,我们将0到20亿的总数相加。
到目前为止,我们已经采用了一种串行方法,在该方法中,您可以计算出0-1亿和1-2亿的结果,然后将它们相加。
我们还将这两个任务分解为并行方法,从而将运行时间减半。
然后,我们将其分为4个进程(我们的班级计算机具有4个内核),每个进程加起来为20亿的1/4,然后让父函数将它们加在一起,这又将运行时间减半。这里包含C语言中的代码。
#include <sys/types.h>
#include <stdio.h>
#include <unistd.h>
#include <sys/wait.h>
#include <sys/time.h>
void sum1b(); //sum 1 to 1 billion
void sum2b(); //sum 1 billion to 2 billion
void sum3b(); //sum 1 to 1 billion
void sum4b(); //sum 1 billion to 2 billion
int main(){
int status;
pid_t pid1 = fork();
//timer
struct timeval start, end;
long mtime, seconds, useconds;
gettimeofday(&start, NULL); //timer
if(pid1 < 0){ //fork failed
fprintf(stderr, "Fork Failed!");
return 1;
}else if(pid1 == 0){ //child process
pid_t pid2 = fork();
if(pid2==0){
pid_t pid3 = fork();
if(pid3==0){
sum4b();
}else{
sum3b();
wait(NULL);
}
}else{
sum2b();
wait(NULL);
}
}else{ //parent process
sum1b();
wait(NULL);
gettimeofday(&end, NULL); //timer
//timer
seconds = end.tv_sec - start.tv_sec;
useconds = end.tv_usec - start.tv_usec;
mtime = ((seconds) * 1000 + useconds/1000.0) + 0.5;
printf("Elapsed time: %ld milliseconds on pid=%d\n", mtime, pid1);
}
return 0;
}
void sum1b(){
long sum =0;
for(int i=1;i<500000000;i++){
sum += i;
}
printf("The sum of 1 to 0.5b is: %ld\n", sum);
}
void sum2b(){
long sum =0;
for(int i=500000000;i<1000000000;i++){
sum += i;
}
printf("The sum of 0.5b to 1b is: %ld\n", sum);
}
void sum3b(){
long sum =0;
for(int i=1000000000;i<1500000000;i++){
sum += i;
}
printf("The sum of 1 to 1.5b is: %ld\n", sum);
}
void sum4b(){
long sum =0;
for(int i=1500000000;i<2000000000;i++){
sum += i;
}
printf("The sum of 1.5b to 2b is: %ld\n", sum);
}
如何将每个结果添加到共享内存空间,然后让父结果收集所有部分结果并返回最终结果?
答案 0 :(得分:0)
您可以使用mmap
分配共享内存,
long *array;
array=(long *)mmap(NULL, sizeof(long)*4, PROT_READ|PROT_WRITE,
MAP_SHARED|MAP_ANONYMOUS, -1, 0);
修改后的代码如下:
#include <sys/types.h>
#include <stdio.h>
#include <unistd.h>
#include <sys/wait.h>
#include <sys/time.h>
#include <sys/mman.h>
void sum1b(long *psum); //sum 1 to 1 billion
void sum2b(long *psum); //sum 1 billion to 2 billion
void sum3b(long *psum); //sum 1 to 1 billion
void sum4b(long *psum); //sum 1 billion to 2 billion
int main()
{
int status, i;
long sum = 0;
long *array;
//timer
struct timeval start, end;
long mtime, seconds, useconds;
gettimeofday(&start, NULL); //timer
array=(long *)mmap(NULL, sizeof(long)*4, PROT_READ|PROT_WRITE,
MAP_SHARED|MAP_ANONYMOUS, -1, 0);
pid_t pid1 = fork();
if(pid1 < 0) { //fork failed
fprintf(stderr, "Fork Failed!");
return 1;
} else if(pid1 == 0) { //child process
pid_t pid2 = fork();
if(pid2==0) {
pid_t pid3 = fork();
if(pid3==0) {
sum4b(array);
} else {
sum3b(array);
wait(NULL);
}
} else {
sum2b(array);
wait(NULL);
}
} else { //parent process
sum1b(array);
wait(NULL);
for(i=0; i<4; i++) {
printf("array[%d]=%ld\n", i, array[i]);
sum += array[i];
}
gettimeofday(&end, NULL); //timer
//timer
seconds = end.tv_sec - start.tv_sec;
useconds = end.tv_usec - start.tv_usec;
mtime = ((seconds) * 1000 + useconds/1000.0) + 0.5;
printf("Elapsed time: %ld milliseconds on pid=%d sum=%ld\n", mtime, pid1, sum);
munmap(array, sizeof(long)*4);
}
return 0;
}
void sum1b(long *psum)
{
long sum =0;
for(int i=1; i<500000000; i++) {
sum += i;
}
psum[0] = sum;
printf("The sum of 1 to 0.5b is: %ld\n", sum);
}
void sum2b(long *psum)
{
long sum =0;
for(int i=500000000; i<1000000000; i++) {
sum += i;
}
psum[1] = sum;
printf("The sum of 0.5b to 1b is: %ld\n", sum);
}
void sum3b(long *psum)
{
long sum =0;
for(int i=1000000000; i<1500000000; i++) {
sum += i;
}
psum[2] = sum;
printf("The sum of 1b to 1.5b is: %ld\n", sum);
}
void sum4b(long *psum)
{
long sum =0;
for(int i=1500000000; i<2000000000; i++) {
sum += i;
}
psum[3] = sum;
printf("The sum of 1.5b to 2b is: %ld\n", sum);
}
但是,建议此方案使用多线程。
祝你好运!