LINUX C 语言--进程管理(一)
2016-07-28 16:34
239 查看
子进程和父进程的开始与结束
子进程结束的时候会向父进程发送信号,让父进程帮助回收进程
父进程先结束的时候,子进程会过继到init进程下(即指定init进程为新的父进程)
如果父进程因为各种原因没有收到子进程发送的信号,则无法回收子进程的资源,子进程会成为僵尸进程
子进程与父进程的资源
进程的内存区划分:代码区、全局区,堆区,代码区
子进程中的资源得到的是父进程的一份拷贝,(包括全局区,栈区,堆区) ,代码区与父进程共享
子进程资源的回收
pid_t wait(int * status);
相当于waitpid(-1,&status,0);
pid_t waitpid(pid_t pid,int * status, int options);
关于pid的参数
< -1 等待所有组id等于pid的绝对值的子进程
= -1 等待所有子进程
= 0 等待所有组id等于父进程组id的子进程
> 0 等待pid为pid的子进程
关于options的参数
WHONG :如果没有子进程结束的话立刻返回
WUNTRACED :
WCONTINUED
返回值:
正常返回pid
错误返回-1 如果所有子进程都已经回收完毕 errno会被设置为 ECHILD
进程的创建
1. fork ():子进程拷贝父进程的数据段,代码段
vfork ( ):子进程与父进程共享数据段
2. fork ()父子进程的执行次序不确定
vfork 保证子进程先运行,在调用exec 或exit 之前与父进程数据是共享的,在它调用exec
或exit 之后父进程才可能被调度运行。
3. vfork ()保证子进程先运行,在她调用exec 或exit 之后父进程才可能被调度运行。如果在
调用这两个函数之前子进程依赖于父进程的进一步动作,则会导致死锁。
进程的终止
正常的终止方式
a.在main函数中执行了return 0;
b.调用exit()函数终止进程
c.调用_exit()/_Exit()函数终止进程
d.最后一个线程返回
e.最后一个线程调用了pthread_exit()函数
非正常的终止方式
a.采用信号终止进程,ctrl+c
b.最后一个线程被其他线程调用了pthread_cancel()取消
atexit(void (* func)(void));注册一个在退出的时候执行的函数
注册的函数将在exit或者return时调用
如果使用_exit()/_Exit()时将不会调用注册的函数
进程管理
wait 函数用于挂起当前正在运行的进程,进入阻塞状态,等待子进程的状态改变(终止)
pid_t wait(int * status)参数用于获取子进程改变的状态
成功返回所等到的子进程的状态,失败返回-1
扩展
调用fork的次数和生成的子进程数量为 2的n次方
创建三个进程
fork();
if(0!=pid)
{
fork();
}
waitpid回收子进程,不包括子进程的子进程
我们创建如下子进程
pid_t p1,p2;
p1 = fork();
if(0 == p1)
{
printf("child of child ,pid is %d\n",fork());
_exit(0);
}
if(0 == p2)
{
printf("child of child ,pid is %d\n",fork());
_exit(0);
}
while(1){
pid_t pres = waitpid(-1,NULL,WNOHANG);
if(pres < 0)
{
if(errno != ECHILD)
{
perror("waitpid");
_exit(-1);
}
printf("all child was died\n");
}
else if(pres)
{
printf("child %d was died \n",pres);
}else
{
printf("do some thing....\n");
sleep(1);
}
}
output:
输出结果可以得出只回收了有主进程创建的两个子进程,而由子进程创建的子进程并没有被回收
子进程结束的时候会向父进程发送信号,让父进程帮助回收进程
父进程先结束的时候,子进程会过继到init进程下(即指定init进程为新的父进程)
如果父进程因为各种原因没有收到子进程发送的信号,则无法回收子进程的资源,子进程会成为僵尸进程
子进程与父进程的资源
进程的内存区划分:代码区、全局区,堆区,代码区
子进程中的资源得到的是父进程的一份拷贝,(包括全局区,栈区,堆区) ,代码区与父进程共享
子进程资源的回收
pid_t wait(int * status);
相当于waitpid(-1,&status,0);
pid_t waitpid(pid_t pid,int * status, int options);
关于pid的参数
< -1 等待所有组id等于pid的绝对值的子进程
= -1 等待所有子进程
= 0 等待所有组id等于父进程组id的子进程
> 0 等待pid为pid的子进程
关于options的参数
WHONG :如果没有子进程结束的话立刻返回
WUNTRACED :
WCONTINUED
返回值:
正常返回pid
错误返回-1 如果所有子进程都已经回收完毕 errno会被设置为 ECHILD
进程的创建
1. fork ():子进程拷贝父进程的数据段,代码段
vfork ( ):子进程与父进程共享数据段
2. fork ()父子进程的执行次序不确定
vfork 保证子进程先运行,在调用exec 或exit 之前与父进程数据是共享的,在它调用exec
或exit 之后父进程才可能被调度运行。
3. vfork ()保证子进程先运行,在她调用exec 或exit 之后父进程才可能被调度运行。如果在
调用这两个函数之前子进程依赖于父进程的进一步动作,则会导致死锁。
进程的终止
正常的终止方式
a.在main函数中执行了return 0;
b.调用exit()函数终止进程
c.调用_exit()/_Exit()函数终止进程
d.最后一个线程返回
e.最后一个线程调用了pthread_exit()函数
非正常的终止方式
a.采用信号终止进程,ctrl+c
b.最后一个线程被其他线程调用了pthread_cancel()取消
atexit(void (* func)(void));注册一个在退出的时候执行的函数
注册的函数将在exit或者return时调用
如果使用_exit()/_Exit()时将不会调用注册的函数
进程管理
wait 函数用于挂起当前正在运行的进程,进入阻塞状态,等待子进程的状态改变(终止)
pid_t wait(int * status)参数用于获取子进程改变的状态
成功返回所等到的子进程的状态,失败返回-1
扩展
调用fork的次数和生成的子进程数量为 2的n次方
创建三个进程
fork();
if(0!=pid)
{
fork();
}
waitpid回收子进程,不包括子进程的子进程
我们创建如下子进程
pid_t p1,p2;
p1 = fork();
if(0 == p1)
{
printf("child of child ,pid is %d\n",fork());
_exit(0);
}
if(0 == p2)
{
printf("child of child ,pid is %d\n",fork());
_exit(0);
}
while(1){
pid_t pres = waitpid(-1,NULL,WNOHANG);
if(pres < 0)
{
if(errno != ECHILD)
{
perror("waitpid");
_exit(-1);
}
printf("all child was died\n");
}
else if(pres)
{
printf("child %d was died \n",pres);
}else
{
printf("do some thing....\n");
sleep(1);
}
}
output:
输出结果可以得出只回收了有主进程创建的两个子进程,而由子进程创建的子进程并没有被回收
相关文章推荐
- Linux socket 初步
- Linux Kernel 4.0 RC5 发布!
- linux lsof详解
- linux 文件权限
- Linux 执行数学运算
- 10 篇对初学者和专家都有用的 Linux 命令教程
- 如何组织构建多文件 C 语言程序(二)
- Linux 与 Windows 对UNICODE 的处理方式
- Ubuntu12.04下QQ完美走起啊!走起啊!有木有啊!
- 解決Linux下Android开发真机调试设备不被识别问题
- 运维入门
- 运维提升
- Linux 自检和 SystemTap
- Ubuntu Linux使用体验
- c语言实现hashmap(转载)
- Linux 信号signal处理机制
- linux下mysql添加用户
- Scientific Linux 5.5 图形安装教程