代码示例
以下代码用以创建两个子进程处理任务,通过基本的代码框架讲解如何使用fork创建很明确的子进程处理任务。
int groupCount = 2;
char *pTaskGroup[2];
pid_t pid = -1;
for (int i = 0; i < groupCount; ++i)
{
pid = fork();
LogInfo("pid --------------11 [%d]", pid);
if (pid == 0 || pid == -1)
{
LogInfo("This is children pid 1 [%d], ...", getpid());
// 若是子进程,则跳出循环执行之后的代码,避免子进程执行循环再 fork()子进程
break;
}
else // parent process
{
for (int i = 0; i < groupCount; i++)
{
if(pTaskGroup[i]->m_TaskPid == 0)
{
// 当前在父进程中,变量pid 表示子进程的pid
LogInfo("pid --------------22 [%d]", pid);
// 将子进程的 pid赋值给当前任务组的变量
pTaskGroup[i]->m_TaskPid = pid;
break;
}
}
}
}
if (pid == -1)
{
LogError("[%s] Fail to fork!\n", __func__);
exit(0);
}
else if (pid == 0) // 子进程
{
LogInfo("This is children pid 2 [%d], ...", getpid());
startTask( );
}
else // 父进程
{
for (int i = 0; i < groupCount; i++)
{
LogInfo("pid [%d]-------------- [%d]", i, pTaskGroup->m_TaskGroup[i]->m_TaskPid);
}
// visionLoop();
}
执行结果说明
[lv:2]: pid --------------11 [12234] <2019-03-21_17:34:20><../src/main.c:143>
[lv:2]: pid --------------22 [12234] <2019-03-21_17:34:20><../src/main.c:157>
[lv:2]: pid --------------11 [0] <2019-03-21_17:34:20><../src/main.c:143>
[lv:2]: This is children pid 1 [12234], ... <2019-03-21_17:34:20><../src/main.c:146>
[lv:2]: This is children pid 2 [12234], ... <2019-03-21_17:34:20><../src/main.c:172>
[lv:2]: pid --------------11 [12235] <2019-03-21_17:34:20><../src/main.c:143>
[lv:2]: pid --------------22 [12235] <2019-03-21_17:34:20><../src/main.c:157>
[lv:2]: pid [0]-------------- [12234] <2019-03-21_17:34:20><../src/main.c:183>
[lv:2]: pid --------------11 [0] <2019-03-21_17:34:20><../src/main.c:143>
[lv:2]: pid [1]-------------- [12235] <2019-03-21_17:34:20><../src/main.c:183>
[lv:2]: This is children pid 1 [12235], ... <2019-03-21_17:34:20><../src/main.c:146>
[lv:2]: This is children pid 2 [12235], ... <2019-03-21_17:34:20><../src/main.c:172>
在执行pid = fork(); 之后子进程已经被创建,此时子进程赋值主进程的所有数据,父进程和子进程同时继续向后执行。通过执行的日志信息可以知道,父进程先执行
// 父进程顺序执行打印了变量pid保存的子进程的id号,同时执行属于父进程的 else部分代码,以下第二行打印。
[lv:2]: pid --------------11 [12234] <2019-03-21_17:34:20><../src/main.c:143>
[lv:2]: pid --------------22 [12234] <2019-03-21_17:34:20><../src/main.c:157>
随后子进程也开始执行
[lv:2]: pid --------------11 [0] <2019-03-21_17:34:20><../src/main.c:143>
[lv:2]: This is children pid 1 [12234], ... <2019-03-21_17:34:20><../src/main.c:146>
[lv:2]: This is children pid 2 [12234], ... <2019-03-21_17:34:20><../src/main.c:172>
因为创建进程fork()在 for循环中,那么当创建子进程完成之后 ,如果不退出当前循环,子进程也会执行for循环,那样的话,子进程又会创建子进程,这样就不符合我们一开始创建2个子进程的初衷。所以才有以下代码。
if (pid == 0 || pid == -1)
{
LogInfo("This is children pid 1 [%d], ...", getpid());
// 若是子进程,则跳出循环执行之后的代码,避免子进程执行循环再 fork()子进程
break;
}
随后创建第二个子进程,顺序和方法同第一个。
主进程在循环中创建子进程完成之后,退出循环,然后在主进程中打印创建的子进程的pid.
[lv:2]: pid [0]-------------- [12234] <2019-03-21_17:34:20><../src/main.c:183>
[lv:2]: pid [1]-------------- [12235] <2019-03-21_17:34:20><../src/main.c:183>

被折叠的 条评论
为什么被折叠?



