Linux系统编程--进程管理的系统调用

fork

#include<unistd.h>
pid_t fork(void);

完成对fork调用后将会存在两个进程,每个进程都会从fork()返回处继续执行。
创建成功,父进程会返回子进程的pid,子进程返回0。
执行fork()时,子进程会获得父进程所有文件描述符的副本。即父子进程对应的描述符指向相同的打开文件句柄。包括:当前文件偏移量、文件状态标志。如果子进程更改了文件偏移量,父进程也会受到影响。

copy-on-write

传统的fork()调用直接将父进程虚拟内存页拷贝到新的子进程,如果在fork()之后立即执行exec()的话,会带来浪费。在现代Linux系统采用两种技术来避免浪费:
1.内核将每一进程代码段标为只读。这样父子进程可以共享同一代码段。
2.对于父进程数据段、堆段、和栈段中各页,采用写时复制技术。最初,内核做了一些设置,令这些段的页表指向与父进程相同的物理页内存,并将这些页表标志为只读。调用fork()之后,内核会捕获所有父子进程针对这些页面的修改企图,并为将要修改的页面创建拷贝。系统将新的页面拷贝分配给遭内核捕获的进程,还会对子进程的相应页表做调整。

fork() 的实际开销就是复制父进程的页表以及给子进程创建唯一的进程描述符。

vfork

产生的子进程将使用父进程内存,直至其调用exec()或退出。与此同时会挂起父进程。

Termination

通常,进程的终止有两种方式。一是异常终止。二是使用_exit()系统调用正常终止。

_exit和exit

#include<unistd.h>
void _exit(int status);

statu参数定义了终止状态,父进程可使用wait获取。
成与一般会调用库函数exit()

#include<stdlib.h>
void exit(int status)

exit()退出会执行如下动作:
调用退出处理程序
刷新stdio流缓冲区
调用_exit()

main()函数中的return(n) 等于exit(n)

无论进程是否正常终止都会发生如下动作
关闭所有打开的文件描述符
释放文件锁
关闭POSIX消息队列
关闭POSIX有名信号量
取消mmap创建的内存映射

exec()

#incude<unistd.h>

int execle(const char* pathname, const char* arg, ...);
int execlp(const char* filename, const char* arg, ...);
int execvp(const char* filename, char *const argv[]);
int execv(const char* pathname, char *const argv[]);
int execl(const char* pathname, const char* arg, ...);

以上函数都是通过

#include<unistd.h>

int execve(const char* pathname, char* const argv[], char *const envp[]);

进行封装的库函数。

函数对程序文件的描述对参数的描述环境变量来源
execve()路径名数组envp参数
execle()路径名列表envp参数
execlp()文件名+PATH列表调用者的environ
exevp()文件名+PATH数组调用者的environ
execv()路径名数组调用者的environ
execl()路径名列表调用者的environ
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值