fork、exec

我们用fork函数创建一个新的进程,也叫当前进程的子进程,子进程是父进程的一个副本,有着和父进程完全一样的数据空间、堆和栈。它们并不共享这些空间。当然,正文段是共享的,因为正文段是只读的。但又因为fork之后经常会跟着exec,所有很多系统又采用了一个写时复制的技术。这技术的大体思路应该是产生子进程后先不要进行完全copy,先是共享这些空间。但内核会把他们设置为只读的。一旦父进程或者子进程要进行写操作时,再复制一个副本。在这里又不得不提一下exec 函数了,exec 函数可以开始一个新的程序,但不会再创建新的进程了,但是它会把当前进程的正文段(代码区域)、堆栈什么的初始化成新程序的执行环境,所有通常是和fork搭配在一起使用的。

vfork

vfork和fork一样也是创建一个新的进程,但是却有些区别的,vfork的数据空间并不是父进程的副本,而是共享的。通常vfork后都紧接着exec或者exit,一般fork后父进程和子进程执行的顺序是不确定的,由内核算法调度的。但vfork却是会执行完子进程直到子进程exec或者exit后才会唤醒父进程。

当一个进程结束后,内核会去判断当前进程是否拥有子进程,如果有子进程。内核会将它所有子进程的父进程项改为init进程(1号进程),确保能够获取到进程的父进程

进程的终止情况

1.main函数调用的return语句,等效于exit

2.调用了exit函数,其操作还包括了调用终止处理程序(通过atexit函数登记的函数,也就是程序终止回调函数)

3.调用了_exit或者_Exit函数,这两个函数也是退出函数,只是它们不会调用终止处理函数,以及不会对标准I/O进行清洗动作(flush)。

4.进程的最后一个线程执行返回语句(该线程的返回值不会作为进程的返回值返回)

5.进程的最后一个线程调用了pthread_exit函数(同上)

进程错误终止

1.调用了abort函数,将产生一个SIGABRT信号,程序异常终止

2.当进程受到某些信号时,信号可能是自己发出的,也可能是其它程序以及内核发出的,比如程序运行出错了,内核就会发出相应的信号

3.最后一个线程对“取消”(cancellation)请求作出响应

 

int setuid(uid_t uid);

之所以要改变用户id,是因为程序需要查看的一些资源,当前用户id可能没有权限。改变用户id的规则

1.如果进程具备超级用户权限,则将实际用户id、有效用户id以及保存设置用户id设置为uid(只有超级用户才能改变实际用户id)

2.如果进程不具备超级用户权限,但uid等于实际用户id或者保存的设置用户id,那么只将有效用户id设置为uid,实际用户id和保存设置用户id不改变

3.以上条件都不具备,将errno设置为EPERM,返回-1

这里假定_POSIX_SAVED_IDS为真,如果没有提供这种功能,那么上面的保存设置的用户id操作都无效

posted on 2013-08-10 15:16  xieweiwei  阅读(174)  评论(0编辑  收藏  举报