进程是正运行于自己的虚拟地址空间的一个具有独立功能的程序,简单地说,进程是程序的一次运行。进程有一定的映像(代码段、数据段和堆栈段),进程是资源的分配单元,进程具有一定的环境。
1、进程的结构
进程上下文描述进程及其运行环境,它由用户级环境(用户栈的内容、用户地址空间的正文段、数据段)、寄存器环境(硬件寄存器的内容)以及系统级环境(PCB、核心栈的内容、区表和页表)等组成。PCB由两部分数据结构构成:进程表项proc结构和user结构(简称u区),proc结构是常驻在内存中,它包含了核心总是要访问的和其他进程要访问的字段;u区包含的是仅在进程运行时所需要访问的字段。因此,仅当创建一进程时,核心才为它分配u区空间;只是在进程运行时,才把当前进程的u区换入内存。
2、进程的状态
进程在运行过程中有三种基本状态:运行态、就绪态和睡眠态(阻塞态)。
3、进程的控制
进程创建:pid_t fork(void);
//#include<sys/types.h>
//#include<unistd.h>
//当调用执行成功时,该调用对父进程返回子进程的PID,对子进程返回0。调用失败时,给父进程返回-1,没有子进程创建。
运行新程序:exec函数
int execl( const char *path, const char *arg, ... , (char *)0);
int execlp( const char *file, const char *arg, ..., (char *)0);
int execv( const char *path, char *const argv[]);
int execvp( const char *file, char *const argv[]);
//#include<unistd.h>
//系统调用exec是用来执行一个可执行文件来代替当前进程的执行映像。需要注意的是,该调用并没有生成新的进程,而是在原有进程的基础上,替换原有进程的正文,调用前后是同一个进程,进程号PID不变。但执行的程序变了(执行的指令序列改变了)。
终止进程:void exit(int status);
//#include<stdlib.h>
进程同步:pid_t wait(int *status);
pid_t waitpid(pid_t pid, int *status, int options);
//#include<sys/types.h>
//#include<sys/wait.h>
//发出wait调用的进程进入睡眠直到它的一个子进程退出时或收到一个不能被忽略的信号时被唤醒。如果调用发出时,已经有退出的子进程(这时子进程的状态是僵死状态),该调用立即返回。其中调用返回时参数status中包含子进程退出时的状态信息。
悬挂进程:unsigned int sleep(unsigned int seconds);
//#include<unistd.h>
其他:
//#include<sys/types.h>
//#include<unistd.h>
uid_t getuid(void);//取得执行目前进程的用户识别码
uid_t geteuid(void);//取得执行目前进程的有效用户识别码
gid_t getgid(void);//取得执行目前进程的组识别码
gid_t getegid(void);//取得执行目前进程的有效组识别码
pid_t getpid(void);//取得目前进程的进程识别码
pid_t getppid(void);//取得目前进程的父进程识别码
pid_t getpgid(pid_t pid);//XSL,取得参数pid指定进程所属的组识别码
pid_t getpgrp(void);//POSIX,取得目前进程所属的组识别码,此函数相当于调用getpgid(0)
pid_t getpgid(pid_t pid);//取得参数pid指定进程所属的组识别码
int setuid(uid_t uid);//设置执行目前进程的用户识别码
int setgid(gid_t gid);//设置执行目前进程的组识别码
int setpgrp(void);//POSIX,将目前进程所属的组识别码设为目前进程的进程识别码
int setpgid(pid_t pid, pid_t pgid);//XSL,将参数pid 指定进程所属的组识别码设为参数pgid指定的组识别码
pid_t getsid(pid_t pid);//返回有pid标识的进程的会话id。会话是进程组的集合。会话对守护进程非常重要,守护进程是没有控制终端的进程。
pid_t setsid();//建立一个新的进程组和会话,并且调用进程的进程id将成为会话id。
//#include<unistd.h>
int chdir(const char *path);//chdir是用来将进程的当前工作目录改为由参数指定的目录。
int chroot(const char *path);//系统调用chroot用来改变发出调用进程的根(“/”)目录。
int nice(int inc);//调用nice将发出调用进程的优先权值增加inc大小。优先权值越低,优先级别越高。
举例如下:
#include<stdio.h>
#include<unistd.h>
#include<sys/types.h>
int main()
{
pid_t pid;
switch (pid=fork())
{
case -1:
printf("fork failed\n");
break;
case 0://child
printf("child pid %d\n", getpid());
printf("child gid %d\n", getgid());
printf("chid uid %d\n", getuid());
printf("child ppid %d\n", getppid());
execl("/bin/ls", "ls", "-l", (char *)0);
printf("execl failed\n");//if execl success, you cannot see this
break;
default:
wait((int *)0);
printf("parent pid %d\n", getpid());
printf("parent gid %d\n", getgid());
printf("parent uid %d\n", getuid());
printf("parent pgrp %d\n", getpgrp());
printf("completed\n");
exit(0);
}
return 0;
}