Chinaunix首页 | 论坛 | 博客
  • 博客访问: 209525
  • 博文数量: 43
  • 博客积分: 2501
  • 博客等级: 少校
  • 技术积分: 485
  • 用 户 组: 普通用户
  • 注册时间: 2007-11-07 21:45
文章分类

全部博文(43)

文章存档

2011年(3)

2010年(1)

2009年(21)

2008年(18)

我的朋友

分类: C/C++

2009-04-05 16:24:01

各种进程ID

#include

pid_t getpid(void);
Returns: process ID of calling process

pid_t getppid(void);
Returns: parent process ID of calling process

uid_t getuid(void);
Returns: real user ID of calling process

uid_t geteuid(void);
Returns: effective user ID of calling process

gid_t getgid(void);
Returns: real group ID of calling process

gid_t getegid(void);
Returns: effective group ID of calling process


fork()和vfork()

#include
pid_t fork(void);
pid_t vfork(void);
Returns: 0 in child, process ID of child in parent, 1 on error

子进程和父进程共享打开的文件,如下图:

因此,子进程和父进程的输出会交织在一起。通常情况下有两种方法避免,一是父进程创建子进程后等待子进程结束(如shell),另一种是父进程和子进程分别关闭不需要的文件(如web server)。

除了打开的文件,子进程从父进程继承了很多其他的属性:
  • Real user ID, real group ID, effective user ID, effective group ID
  • Supplementary group IDs
  • Process group ID
  • Session ID
  • Controlling terminal
  • The set-user-ID and set-group-ID flags
  • Current working directory
  • Root directory
  • File mode creation mask
  • Signal mask and dispositions
  • The close-on-exec flag for any open file descriptors
  • Environment
  • Attached shared memory segments
  • Memory mappings
  • Resource limits
子进程和父进程不同的地方有:
  • The return value from fork
  • The process IDs are different
  • The two processes have different parent process IDs
  • The child's tms_utime, tms_stime, tms_cutime, and tms_cstime values are set to 0
  • File locks set by the parent are not inherited by the child
  • Pending alarms are cleared for the child
  • The set of pending signals for the child is set to the empty set

vfork()和fork()有两点不同:
1.子进程没有拷贝父进程的地址空间,它立即调用exec()或者exit(),调用之前在父进程地址空间运行
2.在子进程调用exec()或者exit()之前,父进程一直等待


exec()

#include

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 []);
All six return: 1 on error, no return on success

其中只有execve()是系统调用,其他的最终都转换成execve(),见下图:


exec()调用之后,进程的text,data,heap,stack等从新文件中载入,但是下面这些属性保持不变:
  • Process ID and parent process ID
  • Real user ID and real group ID
  • Supplementary group IDs
  • Process group ID
  • Session ID
  • Controlling terminal
  • Time left until alarm clock
  • Current working directory
  • Root directory
  • File mode creation mask
  • File locks
  • Process signal mask
  • Pending signals
  • Resource limits
  • Values for tms_utime, tms_stime, tms_cutime, and tms_cstime

而下面这些属性则是会发生改变的:
1.打开的文件。如果exec()之前打开文件的时候使用了FD_CLOEXEC标志,那么exec()会自动关闭该文件。对于普通文件默认是没有FD_CLOEXEC的,也就是说exec()后之前的文件保持打开,然而(用opendir())打开的目录文件默认设置了FD_CLOEXEC,所以打开的目录在exec()后会自动关闭。
2.effective uid/gid。如果可执行文件设置了set-user-id,那么effective uid就是可执行文件的uid,否则不变,gid是一样的。/bin/passwd, /bin/sudo就是典型的set-uid可执行文件。


终止进程

五中正常终止的方式:
  • 1.main()函数中return或者执行完最后一条语句
  • 2.调用exit()结束
  • 3.调用_exit()或_Exit()结束
  • 4.最后一个线程return,返回值为0
  • 5.最后一个线程pthread_exit(),返回值为0

三种异常终止方式:
  • 1.调用abort()
  • 2.收到某种未捕获的信号,如SIGKILL,SIGTERM
  • 3.最后一个线程收到cancel请求并响应


wait()和waitpid()获取终止进程的结束状态

#include
pid_t wait(int *statloc);
pid_t waitpid(pid_t pid, int *statloc, int options);
Both return: process ID if OK, 0 (see later), or 1 on error

wait()的行为如下:
1.如果所有子进程都没有结束,阻塞
2.如果已经有子进程结束,立即返回子进程pid并将子进程结束状态保存在statloc所指的long中
3.如果没有子进程,立即返回错误

waitpid()和wait()不同之处在于:
1.它可以指定等待哪个子进程结束。
  pid_t == 1 指定所有子进程,和wait()等价
  pid_t == 0 指定和调用进程process group id相同的进程
  pid_t > 0  指定进程id是pid_t的进程
  pid_t < 0  指定进程process group id是pid_t的进程
2.可以不用阻塞,如果options中指定WNOHANG
3.通过WUNTRACED WCONTINUED选项支持作业控制

另外,wait3()和wait4()提供了获取子进程使用资源的附加功能,它们分别和wait(),waitpid()对应
#include
#include
#include
#include
pid_t wait3(int *statloc, int options, struct rusage *rusage);
pid_t wait4(pid_t pid, int *statloc, int options, struct rusage *rusage);




阅读(935) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~