使用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输出它的编号)。当所有子进程退出后,主进程显示共享内存区域内的数据。

标签: Linux, C

添加新评论