摘抄网上的pdf文件,有增改。
一:五种状态:
1.新建:表示进程正在被创建。
2.运行:表示进程正在运行。
3.阻塞:进程正在等待某一个事件发生。
4.就绪:表示系统正在等待CPU来执行命令。
5.完成:表示进程已经结束,系统正在回收资源。
二:getpid()可以得到进程
的ID,getppid()可以得到父进程
的ID.
#include<unistd.h>
pid_t getpid(void);
pid_t getppid(void);
getuid可以得到进程的所有者的ID。由于进程要用到一些资源,而Linux对系统资源是进行保护的,为了获取一定的资源,进程还有一个有效用户ID。geteuid()可以得到进程的有效用户ID和用户ID,相对应进程还有一个组ID和有效组ID,系统调用getgid和getegid可以分别得到组ID和有效组ID
getuid——————进程的所有者ID
geteuid————— 有效用户ID和用户ID
getgid——————组ID
getegid—————-有效组ID
getpwuid————--用户其他信息
#include<unistd.h>
#include<sys/types.h>
uid_t getuid(void);
uid_t geteuid(void);
gid_t getgid(void);
gid_t getegid(vodi);
对用户的其他信息感兴趣,可以调用getpwuid来得到。
三:创建一个进程的系统调用——fork()
#include<unistd.h>
pid_t fork();
一个进程调用fork以后,系统会创建一个子进程。子进程和父进程不同的地方只有ID
,其他都一样,就像克隆自己。为了区分子进程和父进程,必须跟踪fork的返回值
,对于父进程fork返回子进程的ID,对于fork子进程返回0。
为什么父进程要创建子进程?
Linux 是一个多用户操作系统,在同一时间会有许多的用户在争夺系统的资源.有时进程为了早一点完成任务就创建子进程来争夺资源. 一旦子进程被创建,父子进程一起从fork 处继续执行,相互竞争系统的资源。
有时候我们希望子进程继续执行,而父进程阻塞知道子进程完成任务。这时候调用wait()或者waitpid()
#include<sys/types.h>
#include<sys/wait.h>
pid_t wait(int *stat_loc)
pid_t waitpid(pid_t pid,int *stat_loc,int options);
wait系统调用会使父进程阻塞
直到一个子进程结束
或者是父进程接受到一个信号
,如果没有父进程没有子进程或他的子进程已经结束了wait会立即返回。成功时(因一个子进程结束)wait将返回子进程的ID
,否则返回-1,并设置全局变量errno.stat_loc是子进程的退出状态
。子进程调用exit,_exit或者是return来设置这个值。为得到这个值,linux定义了几个宏来测试这个返回值。
WIFEXITED:判断子进程退出值是非0
WEXITSTATUS:判断子进程的退出值(当子进程退出时非0)
WIFSIGNALED:子进程由于有 没有获得的信号而退出。
WTERMSIG:子进程没有获得的信号号(在WIFSIGNALED为真时才有意义)
waitpid等待指定的子进程直到子进程返回
。如果pid为正值则等待指定的进程(pid).如果为0则等待任何一个组ID和调用者的组ID相同的进程。
为-1时等同于wait调用
。小于-1时等待任何一个组ID等于pid绝对值的进程。
options可以决定父进程的状态,可以取两个值
WNOHANG:父进程立即返回没有子进程存在时。
WUNTACHED:当子进程结束时waitpid返回,但是子进程的退出状态不可得到。
子进程一般要执行不同的程序,为了调用系统程序,可以使用exec族调用。
#include <unistd.h>;
int execl(const char *path,const char *arg,...);
int execlp(const char *file,const char *arg,...);
int execle(const char *path,const char *arg,...);
int execv(const char *path,char *const argv[]);
int execvp(const char *file,char *const argv[]):
后台进程的创建思想:首先父进程创建一个子进程人然后子进程杀死父进程。信号处理的所有工作由子进程来处理。
(mail例子)