linux系统编程 父进程和子进程fork
linux-dash
A beautiful web dashboard for Linux
项目地址:https://gitcode.com/gh_mirrors/li/linux-dash
免费下载资源
·
stack区和heap区分析
#include <stdio.h>
#include <stdlib.h>
int main(int argc, char * argv[])
{
printf("stack 区\n");
int p = 7;
printf("p = %X\n", &p);
int x = 34;
printf("x = %X\n", &x);
printf("heap 区\n");
char *w = malloc(34);
if (!w)
printf("malloc error\n");
printf("w = %X\n", w);
char *q = malloc(34);
if (!q)
printf("malloc error\n");
printf("q = %X\n", q);
if (w)
{
free(w);
w = NULL;
}
if (q)
{
free(q);
q = NULL;
}
return 0;
}
结构图
由上图可知 stack区 自上往下生长的, heap区是自下往上生长的
一,创建子进程fork函数
pid_t fork(void);
创建成果返回打于0 ,失败返回 小于0
二,exec函数
exec函数族一般规律
exec函数一旦调用成功即执行新的程序,不返回。只有失败才返回,错误值-1。所以通常我们直接在exec函数调用后直接调用perror()和exit(),无需if判断。
- (list) 命令行参数列表
- p (path) 搜素file时使用path变量
- v (vector) 使用命令行参数数组
- e (environment) 使用环境变量数组,不使用进程原有的环境变量,设置新加载程序运行的环境变量
int execl(const char *path, const char *arg, ...
/* (char *) NULL */);
int execlp(const char *file, const char *arg, ...
/* (char *) NULL */);
int execle(const char *path, const char *arg, ...
/*, (char *) NULL, char * const envp[] */);
int execv(const char *path, char *const argv[]);
int execvp(const char *file, char *const argv[]);
int execvpe(const char *file, char *const argv[],
char *const envp[]);
第一个参数是:命令
第二个参数是:命令的名称
m-n的参数 : 参数
最后一位数是:NULL
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
int main(int argc, char *argv[])
{
//pcb 进程控制块
pid_t pid;
//创建子进程
pid = fork();
if (pid < 0)
{
perror("fork error");
exit(1);
}
else if (pid > 0) //父进程
{
printf("father fpid:%d, cpid:%d\n", getpid(), pid);
}
else if (pid == 0) //子进程操作
{
printf("child fpid:%d, cpid:%d\n", getppid(), getpid());
//执行命令参数
execle("./hello", "hello", "陈丽", "王蓉", NULL);
}
return 0;
}
效果图
三,进程孤儿进程和僵尸进程的解释
- 孤儿进程
如果父进程先退出,子进程还没退出,则子进程成为孤儿进程,此时子进程的父进程将变为init进程(托孤给了init进程)。(注:任何一个进程都必须有父进程)。 - 僵尸进程
如果子进程先退出,父进程还没退出,那么子进程必须等到父进程捕获到了子进程的退出状态才真正结束,否则这个时候子进程就成为僵尸(Zombie)进程(僵尸进程:只保留一些退出信息供父进程查询)。
四,wait函数和waitpid函数的使用
pid_t wait(int *status);
pid_t waitpid(pid_t pid, int *status, int options);
- wait函数是当个进程的使用
- waitpid是一个父进程和多个子进程的使用的
- waitpid使用的时候要注意第一个参数默认写 -1 是用来关闭子进程的所有的
/*************************************************************************
> File Name: 父子线程fork.c
> Author: songli
> QQ: 2734030745
> Mail: 15850774503@163.com
> CSDN: http://my.csdn.net/Poisx
> github: https://github.com/chensongpoixs
> Created Time: Thu 19 Oct 2017 10:30:31 PM CST
************************************************************************/
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/wait.h>
#include <sys/types.h>
#include <string.h>
int main(int argc, char *argv[])
{
// pcb 进程控制块 id
pid_t pid;
int i, n = 4;
for (i = 0; i < n; i++)
{
//创建子线程
pid = fork();
if (pid < 0) //异常的处理
{
perror("fork error");
return -1;
}
else if (pid > 0) //父进程的pid
{
printf("father fpid:[%d], cpid:[%d]\n", getpid(), pid);
//sleep(1);
}
else if (pid == 0) //子进程的pid
{
printf("child fpid:[%d], cpid:[%d]\n", getppid(), getpid());
break; //防止子线程中创建子线程
}
}
//==========================子线程的处理================================================
if (i == 0)
{
printf("child id:[%d], cpid:[%d]\n", i, pid);
//子线程关闭在执行中
while(1)
sleep(1);
}
if (i == 1)
{
printf("child id:[%d], cpid:[%d]\n", i, pid);
//子线程关闭在执行中
while(1)
sleep(1);
}
if (i == 2)
{
printf("child id:[%d], cpid:[%d]\n", i, pid);
//子线程关闭在执行中
/*while(1)
sleep(1);*/
perror("no child ----");
return 13;
}
if (i == 3)
{
printf("child id:[%d], cpid:[%d]\n", i, pid);
//子线程关闭在执行中
while(1)
sleep(1);
}
//=======================父进程的处理======================================================
if (i == 4)
{
printf("child id:[%d], cpid:[%d]\n", i, pid);
//父进程的操作线程关闭在执行中
pid_t wpid;
int status;
while (1)
{
//这边第一参数是关闭子线程的pcb的使用不能使用父进程的pcb的pid如果使用会关闭整个进程
wpid = waitpid(-1, &status, WNOHANG);
//判断wpid的返回值操作 子线程的操作
if (wpid == 0) // 子线程在父进程中没有销毁
{
sleep(1);
continue;
}
else if (wpid == -1) //子线程退出的操作
{
printf("子线程:【%d】\n", wpid);
//退出当前子线程 ------------------》 使用waitpid函数第一参数进程退出的
exit(0);
}
else if (wpid > 0) //子线程什么原因退出程序的
{
if (WIFEXITED(status)) // 子线程正常退出程序的操作
{
printf("child:[%d], status:[%d]\n", wpid, WEXITSTATUS(status));
}
if (WIFSIGNALED(status))//signal 信号的处理异常
{
printf("child:[%d], status:[%d]\n", wpid, WTERMSIG(status));
}
}
}
}
return 0;
}
效果图片
GitHub 加速计划 / li / linux-dash
10.39 K
1.2 K
下载
A beautiful web dashboard for Linux
最近提交(Master分支:2 个月前 )
186a802e
added ecosystem file for PM2 4 年前
5def40a3
Add host customization support for the NodeJS version 4 年前
更多推荐
已为社区贡献1条内容
所有评论(0)