记录一个Linux下设计多进程内存共享的C语言代码例子
使用fork创建多个子进程,子进程与主进程共享了一块内存区域,以实现多个CPU核心共同处理一个问题。
例子完整代码如下:
#include <stdio.h>
#include <sys/types.h>
#include <sys/mman.h>
#include <unistd.h>
#include <fcntl.h>
#include <wait.h>
#define CreateCount 10 //创建10个进程
int main(int argc, char *argv[])
{
pid_t pid_result;pid_t pid_list[CreateCount];
int i;
int *shared_mem;
shared_mem=(int *)mmap(NULL,sizeof(int)*CreateCount,PROT_READ|PROT_WRITE,MAP_SHARED|MAP_ANONYMOUS,-1,0);
for(i=0;i<CreateCount;i++)
{
*(shared_mem+i)=0;
}
//创建进程
for(i=0;i<CreateCount;i++)
{
pid_result=fork();
if(pid_result<0)
{
printf("Fork Failed.\n");
}
if(pid_result==0) //子进程,进行数据处理
{
//对共享内存区域进行数据处理,注意不同子进程需要读写不同的内存区域,如果读写的内存区域重叠,注意使用信号量进行进程之间的调控
for(int j=0;j<i;j++)
*(shared_mem+i) += i;
//子进程计算完毕,解除内存映射关系
munmap(shared_mem,sizeof(int)*CreateCount);
//等待一段时间再退出,观察主进程中wait函数的表现
printf("Sub processor %d sleeping.\n",i);
sleep(i);
printf("Sub processor %d exit.\n",i);
return(0);
}
else //主进程,记录PID
{
pid_list[i]=pid_result;
}
}
//主进程创建完毕,等待子进程退出
printf("Waiting Sub Process\n");
while(1)
{
sleep(1);
pid_result=wait(NULL); //主进程阻塞在此处,直到所有子进程执行完毕并退出
for(i=0;i<CreateCount;i++)
{
if(pid_list[i]==pid_result)
{
printf("Main processor: Sub processor %d exit\n",i);
pid_list[i]=(pid_t)0;
}
}
for(i=0;i<CreateCount;i++)
{
if(pid_list[i]>0) //如果存在尚未退出的子进程,则主进程继续等待
break;
}
if(i>=CreateCount) //如果子进程全部退出,则主进程显示计算结果
break;
}
//显示共享内存区域的计算结果
for(i=0;i<10;i++)
printf("Mem[%d]:%d\n",i,*(shared_mem+i));
//释放内存
munmap(shared_mem,sizeof(int)*CreateCount);
return(0);
}
这个例子未使用信号量进行资源调控,所以各子进程读写内容时需要保证运行时涉及到的变量(内存区域)与其他进程无关。
这个例子保存为c文件后在Linux下可以直接使用gcc编译。
执行结果如下:
$ ./main
Sub processor 0 sleeping.
Sub processor 0 exit.
Sub processor 1 sleeping.
Sub processor 2 sleeping.
Sub processor 3 sleeping.
Sub processor 4 sleeping.
Sub processor 5 sleeping.
Sub processor 6 sleeping.
Sub processor 7 sleeping.
Sub processor 8 sleeping.
Waiting Sub Process
Sub processor 9 sleeping.
Sub processor 1 exit.
Main processor: Sub processor 0 exit
Sub processor 2 exit.
Main processor: Sub processor 1 exit
Sub processor 3 exit.
Main processor: Sub processor 2 exit
Sub processor 4 exit.
Main processor: Sub processor 3 exit
Sub processor 5 exit.
Main processor: Sub processor 4 exit
Sub processor 6 exit.
Main processor: Sub processor 5 exit
Sub processor 7 exit.
Main processor: Sub processor 6 exit
Sub processor 8 exit.
Main processor: Sub processor 7 exit
Sub processor 9 exit.
Main processor: Sub processor 8 exit
Main processor: Sub processor 9 exit
Mem[0]:0
Mem[1]:1
Mem[2]:4
Mem[3]:9
Mem[4]:16
Mem[5]:25
Mem[6]:36
Mem[7]:49
Mem[8]:64
Mem[9]:81
其中,当所有进程创建完毕后,主进程会阻塞在wait函数,直到其中一个子进程退出。此时,主进程已经可以着手对相应子进程的计算结果进行处理(但此处未进行处理,仅判断是哪一个子进程退出了,并根据PID输出它的编号)。当所有子进程退出后,主进程显示共享内存区域内的数据。