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>0和pid==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函数中exit和return一样)自动调用。成功返回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设置为value,overwrite=0表示不覆盖,否则覆盖。

intunsetenv(const char *name);

删除环境变量name。

linux常用的环境变量:

HOME

LANG

LOGNAME

PATH

PWD

SHELL

...

#include<setjmp.h>

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

intsetjmp(jmp_buf env);

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

voidlongjmp(jmp_buf env,int val);

发生错误等可以调用该函数,env是setjmp使用的env,val是从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命令。

该函数由fork、exec、waitpid三个函数组成:

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

#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.

未完待续......

时间: 2024-11-08 16:15:53

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

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

本文主要总结和系统相关的文件和信息的系统调用和库函数. ####################################################### 系统相关的系统调用 ####################################################### #include <sys/types.h> #include <unistd.h> int getgroups(int size, gid_t list[]); 获取附加组ID,成功返

APUE: 信号相关系统调用和库函数

信号就是软件中断,信号提供一种处理异步事件的方法. 信号出现时按照下列方式处理: 1.忽略此信号,有两个信号不能忽略. 2.捕捉此信号,有两个信号不能被捕捉. 3.默认处理,少数默认处理是忽略,大部分默认处理是终止. ctrl+D组合键,不是信号,只是EOF字符 linux中1-31为普通信号:34-64为实时信号. trap-l 命令查看所有信号,64个 信号从1开始,没有0. SIGHUP:终端接口检测到连接断开发出该信号, SIGINT:ctrl+c,终端中断符,一般用来停止一个失去控制的

sockets: 套接字选项相关的系统调用

########################################################### 套接字选项相关的系统调用: ########################################################### 将optval指向的单元中的值设置给optname选项: int setsockopt(int sockfd, int level, int optname, const void *optval,socklen_t optlen)

Linux进程相关的内容及命令小结(一)

概念:进程,一个活动的程序实体的副本,拥有生命周期,一个进程可能包含一个或多个执行流: 进程的创建进程:  每个进程的组织结构是一致的:  内核在正常启动并且全面接管硬件资源之后,会创建一个Init的进程:而这个名叫init的进程负责用户空间的进程管理:  CentOS5及以前:SysV Init,Classic Init  在启动系统时,Init通过写脚本的方式来创建各个子进程:利用shell来实现,因此其执行速度非常慢:导致系统的启动速度和进程的创建速度都非常慢:  CentOS6:upst

Linux - 系统调用与库函数

文件基本概念 文件 可被读写的对象 具备一定权属性,包括访问权限.类型等 文件系统 文件及其属性的集合,提供了命名及管理机制 文件结构 字节流,没有特定内部结构 文件类型 普通文件 目录 设备文件 字符文件/块文件 FIFO文件(如管道文件) Socket文件 符号链接 硬连接 不同的文件名对应同一个inode 不能跨越文件系统 相应系统调用 link() [root@localhost link]# ls -l total 1 -rw-r--r-- 1 root root 667 Oct 15

linux-man命令中的编号含义(包括系统调用和库函数讲解)

博文说明[前言]: 本文将通过个人口吻介绍linux的man命令中的编号含义(包括系统调用和库函数解释),在目前时间点[2017年6月13号]下,所掌握的技术水平有限,可能会存在不少知识理解不够深入或全面,望大家指出问题共同交流,在后续工作及学习中如发现本文内容与实际情况有所偏差,将会完善该博文内容. 本文参考文献引用链接: 1.http://www.cnblogs.com/chao1118/p/3715523.html2.http://blog.csdn.net/high_high/artic

linux内核中与进程相关的数据结构(基于linux-mainline-rc4)

1.进程描述符    struct task_struct {  volatile long state; ....... struct list_head tasks; ....... struct mm_struct *mm, *active_mm; ....... struct vm_area_struct *vmacache[VMACACHE_SIZE]; ...... pid_t pid; pid_t tgid; .......   }所在文件:include/linux/sched.

linux下多进程的文件拷贝与进程相关的一些基础知识

之前实现了用文件IO的方式可以实现文件的拷贝,那么对于进程而言,我们是否也可以实现呢? 答案是肯定的. 进程资源: 首先我们先回顾一下,进程的运行需要哪些资源呢?其资源包括CPU资源,内存资源,当然还有时间片资源,我们都知道进程是有 栈, 堆,  只读数据段,  数据段(已初始化的全局变量静态变量),bss段(未初始化的),   代码段还有一组寄存器值. 进程命令: 另外我们也可以通过 ps  -ef |grep 进程名命令来查看进程号(PID)和父进程号(PPID),之后还可以通过 ps au

获取 窗口 进程 相关信息

GameHwnd:= FindWindow(nil,'对对碰角色版'); //得到进程ID GetWindowThreadProcessId(GameHwnd,GamePid); //得到进程句柄 GameProcess:= OpenProcess(PROCESS_VM_READ or PROCESS_VM_WRITE,False,GamePid); //读取进程内存 ReadProcessMemory(GameProcess,Pointer($0048F128),@sitnum,4,readb