Linux进程控制(一)

一、进程标识符

#include<unistd.h>

pid_t getpid(void);

         返回值:调用进程的进程ID

pid_t getppid(void);

         返回值:调用进程的父进程ID

uid_t getuid(void);

         返回值:调用进程的实际用户ID

uid_t geteuid(void);

         返回值:调用进程的有效用户ID

gid_t getgid(void);

         返回值:调用进程的实际组ID

gid_t getegid(void);

         返回值:调用进程的有效组ID


二、创建进程fork函数

#include<unistd.h>

pid_t fork(void);

         返回值:子进程中返回0,父进程中返回子进程ID,出错返回-1

子进程和父进程继续执行fork调用之后的指令,子进程是父进程的副本。父、子进程共享正文段。


文件共享:

fork的一个特性是父进程的所有打开文件描述符都被复制到子进程中。父子进程的每个相同的打开描述符共享一个文件表项。

除了打开文件外,父进程的很多其他属性也由子进程继承,包括

(1)实际用户ID、实际组ID、有效用户ID、有效组ID

(2)附加组ID

(3)进程组ID

(4)会话ID

(5)控制终端

(6)设置用户ID标志和设置组ID标志

(7)当前工作目录

(8)根目录

(9)文件模式创建屏蔽字

(10)信号屏蔽和安排

(11)针对任一打开文件描述符的在执行时关闭(close-on-exec)标志

(12)环境

(13)连接的共享存储段

(14)存储映射

(15)资源限制

父、子进程之间的区别是:

(1)fork的返回值

(2)进程ID不同

(3)两个进程具有不同的父进程ID

(4)子进程的tms_utime、tms_stiem、tms_cutime以及tms_ustime均被设置为0

(5)父进程设置的文件锁不会被子进程继承

(6)子进程的未处理的闹钟被清除

(7)子进程的未处理信号集设置为空集


创建进程vfork函数

vfork用于创建一个新进程,而该新进程的目的是exec一个新程序,在子进程调用exec或exit之前,它在父进程的地址空间运行。

vfork与fork的另一个区别:vfork保证子进程先运行,在它调用exec或exit之后父进程才可能被高度运行。如果在调用这两个函数之前子进程依赖于父进程的进一步动作,则会导致死锁。


exit函数

如果父进程在子进程之前终止,对于父进程已经终止的所有进程,它们的父进程都改变为ini进程。只要有一个子进程终止,init就会调用一个wait函数取得其终止状态。

一个已经终止、但是其父进程尚未对其进行善后处理(获取终止子进程的有关信息,释放它仍占有的资源)的进程被称为僵死进程(zombie)。内核为每个终止子进程保存了一定量的信息,所以当终止进程的父进程调用wait或waitpid时,可以得到这些信息。


wait和waitpid函数

当一个进程正常或异常终止时,内核就向其父进程发送SIGCHLD信号。调用wait或waitpid时可能发生的情况:

(1)如果其所有子进程都还在运行,则阻塞

(2)如果一个子进程已终止,正等待父进程获取其终止状态,则取得该子进程的终止状态立即返回

(3)如果它没有任何子进程,则立即出错返回

#include<sys/wait.h>

pid_t wait(int *statloc);

pid_t waitpid(pid_t pid, int *statloc, int options);

           两个函数返回值:若成功则返回进程ID,若出错则返回-1

两个函数的区别:

(1)在一个子进程终止前,wait使其调用者阻塞,而waitpid有一个选项,可使调用者不阻塞

(2)waitpid并不等待在其调用之后的第一个终止子进程,它有若干选项,可以控制它所等待的进程

两个函数的statloc是一个整形指针,可通过宏检查终止状态。

pid参数作用解释:

pid == -1  等待任一子进程。就这一方面而言,waitpid与wait等效

pid > 0  等待其进程ID与pid相等的子进程

pid == 0 等待其组ID等于调用进程组ID的任一子进程

pid < -1 等待其组ID等于pid绝对值的任一子进程


exec函数

当进程调用一种exec函数时,该进程执行的程序会完全替换为新程序,而新程序则从其main函数开始执行。因为调用exec并不创建新进程,所以前后的ID并未改变。exec只是用一个全新的程序替换了当前进程的正文、数据、堆和栈段。

#include<unistd.h>

int execl(const char *pathname, const char *arg0, ... /*  (char *) 0 */);

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

int execle(const char *pathname, const char *arg0, ... /* (char  *)0, char *const envp[ ] */);

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

int execlp(const char *filename,  const char *arg0, ... /* (char *)0  */);

int execvp(const char *filename, char *const argv[ ]);

           六个函数的返回值:若出错则返回-1,成功则不返回值

注:

如果filename中包含/,则将其视为路径名(与execl或execv一样?)

否则就按PATH环境变量,在它所指定的各目录中搜寻可执行文件。

(l表示list,v表示矢量vector,p表示该函数取filename作为参数),以e结尾的两个函数可以传递一个指向环境字符串指针数组的指针。


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值