Chinaunix首页 | 论坛 | 博客
  • 博客访问: 1879283
  • 博文数量: 184
  • 博客积分: 0
  • 博客等级: 民兵
  • 技术积分: 2388
  • 用 户 组: 普通用户
  • 注册时间: 2016-12-21 22:26
个人简介

90后空巢老码农

文章分类

全部博文(184)

文章存档

2021年(26)

2020年(56)

2019年(54)

2018年(47)

2017年(1)

我的朋友

分类: LINUX

2020-04-05 19:34:43

进程的创建

系统调用fork()允许一个进程创建一个新进程,子进程获得父进程的栈、数据段、堆和执行文本段的拷贝

点击(此处)折叠或打开

  1. #include <unistd.h>
  2. pid_t fork(void);
  3. /* in parent: returns process ID of child on success, or -1 on error; in successfully created child: always returns 0*/
大部分现代UNIX实现采用两种计数来避免浪费内存:
1. 将每一个进程的代码段标记为只读,是父子进程可以共享同一代码段
2. 对于父进程的数据段、堆段、栈段当中的各页,内核采用写时复制(copy-on-write)计数来处理
为了子进程立即执行exec()的程序而专门设计的vfork()

点击(此处)折叠或打开

  1. #include <unistd.h>
  2. pid_t vfork(void);
  3. /* in parent: returns process id of child on success, or -1 on error; in successfully created child: always returns 0*/
vfork()因为如下两个特性而更具效率:
1. 无需为子进程复制虚拟内存页或页表。相反,子进程共享父进程的内存,直至其成功执行了exec()或是调用_exit()退出。
2. 在子进程调用exec()或_exit()之前,将暂停执行父进程


进程的终止:
系统调用:

点击(此处)折叠或打开

  1. #include <unistd.h>
  2. void _exit(int status);
  3. #include <stdlib.h>
  4. void exit(int status);
其中exit()会执行以下动作:
1. 调用退出处理程序(通过atexit()和on_exit()注册的函数),其执行顺序与注册顺序相反
2. 刷新stdio流缓冲区
3. 使用由status提供的值执行_exit()系统调用

进程终止的细节
无论进程是否正常终止,都会发生如下动作:
1.  关闭所有打开文件描述符、目录流信息、目录描述符,以及(字符集)转换描述符
2. 作为文件描述符关闭的后果之一,将释放该进程所持有的任何文件锁
3. 分离(detach)任何已连接的System V共享内存段,且对应于各段的shm_nattch计数器值将减1
4. 进程为每个System V信号量所设置的semadj值将会被加到信号量值中
5. 如果该进程是一个管理终端的管理进程,那么系统会向该终端前台进程组中的每个进程发送SIGHUP信号,接着终端会与会话(session)脱离
6. 将关闭该进程打开的任何POSIX有名信号量,类似于调用sem_close()
7. 将关闭该进程打开的任何POSIX消息队列,类似于调用mq_close()
8. 作为进程退出的后果之一,如果某进程组称为孤儿,且该组中存在任何已停止进程,则组中所有进程都将受到SIGHUP信号,随之为SIGCONT信号
9. 移除该进程通过mlock()或mlockall()所创建的任何内存锁
10. 取消该进程调用mmap()所创建的任何内存映射

退出处理程序:
如果程序直接调用_exit()或因信号而异常终止,则不会调用退出处理程序


点击(此处)折叠或打开

  1. #include <stdlib.h>
  2. int atexit(void (*func)(void));
  3. /*returns 0 on success, or nonzero on error*/
一旦有任一退出处理程序无法返回,那么就不会再调用剩余的处理程序


阅读(1499) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~