APUE: 进程相关的系统调用和库函数

进程正常终止5种方式:

1.main函数返回

2.调用exit库函数

3.调用_exit_Exit系统调用

4.最后一个线程从其启动例程返回

5.最后一个线程调用pthread_exit库函数

进程异常终止3种方式:

1.调用abort库函数,产生abort信号。

2.接到一个信号并终止

3.最后一个线程对取消请求做出响应


init进程:pid=1的进程,如果父进程先于子进程终止,子进程就被init进程收养。

孤儿进程:父进程先于子进程退出,子进程被init进程收养,这个子进程就是孤儿进程。

僵死进程:已经终止,但是父进程没有进行善后处理的进程。


##################################################

进程相关的系统调用

##################################################

#include<unistd.h>

void_exit(int status);


#include<stdlib.h>

void_Exit(int status);


#include<sys/time.h>

#include<sys/resource.h>

intgetrlimit(int resource, struct rlimit *rlim);

传入资源名称返回资源结构信息。

intsetrlimit(int resource, const struct rlimit *rlim);

设置资源结构。


structrlimit {

rlim_trlim_cur; //软限制

rlim_trlim_max; //硬限制

};


resource:

RLIMIT_AS

RLIMIT_CORE

RLIMIT_CPU

RLIMIT_DATA

RLIMIT_FSIZE

RLIMIT_LOCKS

RLIMIT_MEMLOCK

RLIMIT_MSGQUEUE

RLIMIT_NICE

RLIMIT_NOFILE

RLIMIT_NPROC

RLIMIT_RSS

RLIMIT_RTPRIO

RLIMIT_RTTIME

RLIMIT_SIGPENDING

RLIMIT_STACK


#include<unistd.h>

#include<sys/types.h>

pid_tgetpid(void);

返回调用进程的进程ID

pid_tgetppid(void);

返回调用进程的父进程ID


uid_tgetuid(void);

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

uid_tgeteuid(void);

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

intsetuid(uid_t uid);

设置调用进程的实际用户ID和有效用户ID

只有超级用户可以改变实际用户ID

普通用户只能改变有效用户ID

intseteuid(uid_t euid);

更改有效用户ID

intsetreuid(uid_t ruid, uid_t euid);

交换实际用户ID和有效用户ID的值,如果有一个参数为-1,表示相应的值不变。


gid_tgetgid(void)

返回调用进程的实际组ID

gid_tgetegid(void);

返回调用进程的有效组ID

intsetgid(gid_t gid);

设置调用进程的实际组ID和有效组ID

intsetegid(gid_t egid);

更改有效组ID

intsetregid(gid_t rgid, gid_t egid);

交换实际组ID和有效组ID的值,如果有一个参数为-1,表示相应的值不变。


#include<unistd.h>

pid_t getpgid(pid_t pid);

成功返回进程组ID,失败返回-1.pid=0,返回调用进程的进程组ID

pid_tgetpgrp(void);

返回调用进程的进程组ID

intsetpgid(pid_t pid, pid_t pgid);

加入现有的组,或创建一个新进程组。

一个进程只能为自己或子进程设置组ID,子进程调用exec之后也不能设置组ID

pid进程的进程组ID设置为pgid;如果pid=0,则pid=调用者的进程ID,如果pgid=0,则pgid=pid

成功返回0,失败返回-1.


#include<unistd.h>

pid_tsetsid(void);

成功返回进程组ID,失败返回-1.

创建一个新的会话,如果调用进程是组长进程则失败,否则调用进程变成新会话首进程和新进程组组长进程,且该进程没有控制终端。

pid_tgetsid(pid_t pid);

返回会话首进程的进程组ID,失败返回-1.

如果pid=0返回调用进程的会话首进程组ID


#include<unistd.h>

pid_tfork(void); //创建新进程。

调用一次,返回两次,在父进程返回子进程的ID,在子进程返回0.

Pid= fork()

pid>0只是父进程执行

pid==0只是子进程执行

后面的不在pid>0pid==0范围之内的程序,父子进程都要执行,除非某个进程终止了。


子进程继承父进程的下列属性:

1.父进程的所有的打开的文件描述符

2.实际用户ID和组ID、有效用户ID和组ID

3.附加组ID、进程组ID、会话ID

4.设置用户ID标识和设置组ID标志。

5.控制终端、根目录、当前工作目录

6.文件模式创建屏蔽字、信号屏蔽和安排

7.环境、存储映像、资源限制、连接的共享存储段

8.针对任一打开文件描述符的在执行时关闭标志。


子进程和父进程的区别:

1.进程ID不同

2.父进程ID不同

3.父进程设置的文件锁不会被继承

4.子进程的未处理的闹钟被清理

5.子进程的未处理信号集设置为空集

6.子进程的tms_utime,tms_stime,tms_cutime,tms_ustime设置为0.


#include<sys/types.h>

#include<sys/wait.h>

pid_twait(int *status); //= waitpid(-1, &status, 0);

参数用来保存进程退出时的状态,不关心可以为NULL

返回子进程的ID,出错返回-1.

进程一旦调用wait,就立即阻塞自己,如果一个子进程是僵死进程,wait立即返回,并取得该子进程的退出状态;否则等到当前进程的某个子进程终止才返回。


pid_twaitpid(pid_t pid, int *status, int options);

status参数用来保存进程退出时的状态,不关心可以为NULL

成功返回已经终止子进程的ID;如果WNOHANG指定,pid指定的进程状态都没有变化,返回0;出错返回-1


pid

指定要等待的进程ID

-1:等待任何子进程,和wait一样

<-1:等待组ID=|pid|的子进程

0: ID=调用进程组ID的任何子进程

>0:等待ID=pid的指定子进程


options:可以是0.

WNOHANG:指定的子进程不能立即可用,不阻塞,函数返回0.

WUNTRACED:指定的子进程处于暂停状态,状态没报告,返回其状态。

WCONTINUED:指定的子进程在暂停后继续,状态没报告,返回其状态。


可用宏判断一些status状态:

WIFEXITED(status),如果子进程正常退出,返回真。

WEXITSTATUS(status),返回子进程退出状态,取低8位。

WIFSIGNALED(status),如果是异常终止子进程,返回真。

WTERMSIG(status):获取异常退出的信号。

WIFSTOPPED(status):若为当前暂停子进程的返回状态,返回真。

WSTOPSIG(status):获取暂停进程的信号。

WCOREDUMP(status):产生core文件,返回真。

WIFCONTINUED(status):若在作业暂停后已经继续的子进程返回了状态,返回真。只能用于waitpid


intwaitid(idtype_t idtype, id_t id, siginfo_t *infop, intoptions);

成功返回0,失败返回-1.


idtype

P_PID:等待一个特定的进程,id包含要等待子进程的进程ID

P_PGID:等待一个特定进程组中的任一子进程,id包含要等待子进程的进程组ID

P_ALL:等待任一子进程,ID忽略。


Options:

WCONTINUED:等待一个暂停后又继续的进程,状态未报告。

WEXITED:等待已退出的进程

WNOHNAG:如果没有可用的子进程退出状态,立即返回

WNOWAIT:不破坏子进程退出状态

WSTOPPED:等待一个暂停的进程,状态未报告。


intexecve(const char *path, char *const argv[], char *constenvp[]);//参数数组,只有这个函数是系统调用。

exec的一个系统调用,其它留个库函数都是调用这个函数。


#include<sys/times.h>

clock_ttimes(struct tms *buffer);

返回的是墙上时钟时间,失败返回-1.两次调用获取的时间差才是真正滴答数。

返回的墙上时钟时间(滴答数)需要用_SC_CLK_TCK宏转换成秒,也就是用滴答数/sysconf_SC_CLK_TCK)=实际时间(rtime


structtms {

clock_ttms_utime; //用户cpu时间

clock_ttms_stime; //系统cpu时间

clock_ttms_cutime; //终止子进程的用户cpu时间

clock_ttms_cstime; //终止子进程的系统cpu时间

}


##################################################

进程相关库函数

##################################################


#include<stdlib.h>

voidexit(int status);

status:

0:= EXIT_SUCCESS , exit with normal

1:= EXIT_FAILURE , exit with failure


#include<stdlib.h>

intatexit(void (*function)(void));

调用该函数注册终止处理程序,这些程序由exit(在mai函数中exitreturn一样)自动调用。成功返回0,失败返回非0.

参数是终止处理程序的地址,该函数没有参数和返回值。


#include <stdlib.h>

存储器分配函数:

成功返回非空指针,失败返回NULL

void*malloc(size_t size);

分配指定字节的存储区,用于整型、浮点型、字符和字符串。

void*calloc(size_t nmemb, size_t size);

分配指定数量和指定长度的对象,用于结构、结构数组、数组等

void*relloc(void *ptr, size_t newsize);

更改以前分配区的长度。

存储器释放函数:

voidfree(void *ptr);


#include<stdlib.h>

char*getenv(const char *name);

根据环境变量名字name返回它的值,出错返回NULL

intsetenv(const char *name, const char *value, int overwrite);

将环境变量name设置为valueoverwrite=0表示不覆盖,否则覆盖。

intunsetenv(const char *name);

删除环境变量name


linux常用的环境变量:

HOME

LANG

LOGNAME

PATH

PWD

SHELL

...


#include<setjmp.h>

处理子函数中发生的错误和中断:

intsetjmp(jmp_buf env);

在希望返回的地方调用该函数,直接调用返回0.longjmp调用返回非0val


voidlongjmp(jmp_buf env,int val);

发生错误等可以调用该函数,envsetjmp使用的envval是从setjmp返回的非0值。


exec的六个函数:执行一个新程序。

出错返回-1,成功不返回。

#include<unistd.h>

externcahr **environ;


用程序路径:

intexecl(const char *path, const char *arg0,…, (char*)0);//单个参数传递,最后要用0结束

intexecv(const char *path, char *const argv[]);//参数数组


用程序路径,带环境变量

intexecle(const char *path, const char *arg0, …, (char *)0,char *const envp[]);//单个参数,要用0结束


用程序名称:

intexeclp(const char *file, const char *arg0,…, (char *)0);//单个参数,要用0结束

intexecvp(const char *file, char *const argv[]);//参数数组


用程序名称,带环境变量

intexecvpe(const char *file, char *const argv[], char *constenvp[]); //参数数组


exec函数执行新程序的进程保持了原进程的下列特性:

1.进程ID和父进程ID、实际用户ID和实际组ID、附加组Id和进程组ID、会话ID

2.控制终端

3.闹钟尚余留的时间

4.当前工作目录、根目录

5.文件模式创建屏蔽字、文件锁

6.进程信号屏蔽、未处理信号

7.资源限制

8.tms_utime\tms_stime\tms_cutime\tms_cstime的值。


#include <stdlib.h>

intsystem(const char *command);

执行一个shell命令。

该函数由forkexecwaitpid三个函数组成:

失败返回-1exec不能执行不算失败;成功返回退出状态,可以根据waitpidstatus宏检验和获取退出状态。


#include<unistd.h>

char*getlogin(void);

用来查找运行当前进程的用户名

成功返回指向登录名的指针,失败返回NULL


#include<termios.h>

pid_ttcgetsid(int fd);

返回会话首进程的进程组ID,失败返回-1.


#include<unistd.h>

pid_ttcgetpgrp(int fd);

返回前台进程组的进程组ID,出错返回-1.

inttcsetpgrp(int fd, pid_t pgrp);

设置前台进程组ID,成功返回0,失败返回-1.


未完待续......

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值