linux下进程相关操做

1、定义和理解
狭义定义:进程是正在运行的程序的实例。
广义定义:进程是一个具备必定独立功能的程序关于某个数据集合的一次运行活动。
进程的概念主要有两点:
第一,进程是一个实体。 每个进程都有它本身的地址空间,通常状况下,包括文本区域、数据区域和堆栈区域。文本区域存储处理器执行的代码;数据区域存储变量和进程执行期间使用的动态分配的内存;堆栈区域存储着活动过程调用的指令和本地变量。
第二,进程是一个“执行中的程序”。程序是一个没有生命的实体,只有处理器赋予程序生命时,它才能成为一个活动的实体,咱们称其为进程。
 
进程的属性
进程标志符:进程ID,内核分配,该标志符非负,范围0~32767
父进程和父进程ID(PPID) 
启动进程的用户ID(UID)和所归属的组(GID);
进程的有效用户ID和有效组ID   
进程的进程组ID:一个进程能够属于某一个进程组。
进程的会话ID:每个进程都属于唯一的会话。 
进程状态:状态分为运行R、休眠S、阻塞Z;
进程执行的优先级;
进程所链接的终端名;
进程资源占用:好比占用资源大小(内存、CPU占用量);
2、进程的相关操做
(1)获取进程属性和更改属性
获取:
getpid(void) 获取当前进程ID
getppid(void) 获取当前进程的父进程ID
getpgrp(void) 获取当前进程的进程组ID
getpgid(pid_t pid) 获取进程组ID
getuid(void) 获取当前进程的用户ID
geteuid(void) 获取当前进程的有效用户ID
getgid(void) 获取当前进程的用户组ID
getegid(void) 获取当前进程的有效用户组ID
getsid(pid_t pid) 获取当前进程的会话ID
设置:
int setpgid(pid_t pid,pid_t pgid)
setpgid()将参数pid 指定进程所属的组ID设为参数pgid 指定的组识别码。若是参数pid 为0,则会用来设置目前进程的组ID,若是参数pgid为0,则会以 
目前进程的进程ID来取代。
int setpgrp(void)  
setpgrp()将目前进程所属的组ID设为目前进程的进程ID。此函数至关于调用setpgid(0,0)。  
pid_t setsid(void)  
setsid函数,调用该函数的进程将做为新会话的领导者建立一个新的会话,会话和调用进程的进程组ID,将被设置为调用进程的进程ID,并返回该进程ID 
int setuid(uid_t uid) 设置进程的用户ID
int setreuid(uid_t ruid, uid_t euid) 将进程的实际用户ID设置为ruid,有效用户ID设置为euid
int seteuid(uid_t uid) 设置进程的有效用户ID为uid
int setgid(gid_t gid) 设置进程的组ID
int setregid(gid_t rgid, gid_t egid) 将进程的实际组ID设置为rgid,有效组ID设置为egid
int setegid(gid_t gid) 设置进程的有效组ID
进程优先级: linux系统为多进程同时运行,Linux采用了时间片轮转的进程调度方式。进程的优先级定义了进程被调度的优先顺序,优先级的数值越低,其优先级就越高。  
Linux用nice系统调用来修改进程的优先级,默认状况下,进程的优先级为0,系统容许的优先级的 范围为:-20~2
int nice(int inc)  
nice()用来改变进程的进程执行优先顺序。参数inc数值越大则优先顺序排在越后面,即表示进程执行会越慢。  只有超级用户才能使用负的inc值,表明优先顺序排在前面,进程执行会较快。返回值  若是执行成功则返回0,不然返回-1,失败缘由存于errno中。错误代码  EPERM 通常用户企图转用负的参数inc值改变进程优先顺序。 nice系统调用只能用于修改进程自身的优先级。
setpriority(设置程序进程执行优先权)
定义函数  int setpriority(int which,int who, int prio);
函数说明  setpriority()可用来设置进程、进程组和用户的进程执行优先权。参数which有三种数值,
参数 who则依which值有不一样定义
which     who 表明的意义
PRIO_PROCESS     who为进程ID
PRIO_PGRP           who为进程的组ID
PRIO_USER          who为用户ID
参数prio介于-20 至20 之间。表明进程执行优先权,数值越低表明有较高的优先次序,执行会较频繁。 
此优先权默认是0,而只有超级用户(root)容许下降此值。返回值  执行成功则返回0,若是有错误发生返回值则为-1,错误缘由存于errno。 ESRCH 参数which或who 可能有错,而找不到符合的进程EINVAL 参数which值错误。EPERM 权限不够,没法完成设置 EACCES
通常用户没法下降优先权
int getpriority(int which,int who);
函数说明  getpriority()可用来取得进程、进程组和用户的进程执行优先权。 参数  which有三种数值,参数who 则依which值有不一样定义
which             who 表明的意义
PRIO_PROCESS    who 为进程ID
PRIO_PGRP         who 为进程的组ID
PRIO_USER         who 为用户ID
此函数返回的数值介于-20 至20之间,表明进程执行优先权,数值越低表明有较高的优先次序,执行会较频繁。 返回值  返回进程执行优先权,若有错误发生返回值则为-1 且错误缘由存于errno。附加说明  因为返回值有多是-1,所以要同时检查errno是否存有错误缘由。最好在调用次函数前先清除errno变量。错误代码  ESRCH 参数which或who 可能有错,而找不到符合的进程。EINVAL 参数which 值错误。
 
(2)建立进程
一、int fork( void );
返回值:子进程中返回0,父进程中返回子进程ID,出错返回-1  
函数说明:一个现有进程能够调用fork函数建立一个新进程。由fork建立的新进程被称为子进程(child process)。  
fork函数被调用一次但返回两次。两次返回的惟一区别是子进程中返回0值而父进程中返回子进程ID。  
子进程是父进程的副本,它将得到父进程数据空间、堆、栈等资源的副本。
注意,子进程持有的是上述存储空间的“副本”,这意味着父子进程间不共享这些存储空间,它们之间共享的存储空间只有代码段。
深刻理解能够参见:linux中fork()函数详解 http://os.chinaunix.net/a2012/0203/1306/000001306508.shtml
二、int vfork( void );
返回值:子进程中返回0,父进程中返回子进程ID,出错返回-1  
vfork与fork大体相同,区别以下:
1) fork要拷贝父进程的数据段;而vfork则不须要彻底拷贝父进程的数据段,在子进程没有调用exec和exit以前,子进程与父进程共享数据段
2) fork不对父子进程的执行次序进行任何限制;而在vfork调用中,子进程先运行,父进程挂起,直到子进程调用了exec或exit以后,父子进程的执行次序才再也不有限制
 
(3)exec函数族
在fork后的子进程中使用exec函数族,能够装入和运行其它程序(子进程替换原有进程,和父进程作不一样的事)。 fork建立一个新的进程就产生了一个新的PID,exec启动一个新程序,替换原有的进程,所以这个新的被 exec 执行的进程的PID不会改变(和调用exec的进程的PID同样)。
 
(4)进程等待
一、pid_t wait (int * status);
函数说明: wait()函数的工做过程是:先判断子进程是否存在,便是否成功建立了一个子进程。若是建立失败,则会直接退出并提示相关错误信息,并返回-1;若是建立成功,wait()将父进程挂起,直到子进程结束,并返回子进程结束时的状态和PID。
若是有子进程,退出时的结束状态(status)有如下两种:
1)子进程正常结束:如调用exit(0)。
2)信号引发子进程结束:如调用kill(pid_t pid, int sig);
若是不在乎结束状态值,则参数status 能够设成NULL。
 
二、 pid_t waitpid(pid_t pid,int * status,int options);
 返回值:若是执行成功则返回子进程识别码(PID),若是有错误发生则返回-1。失败缘由存于errno 中。
 函数说明: waitpid()会暂时中止目前进程的执行,直到有信号来到或子进程结束。若是在调用 wait()时子进程已经结束,则wait()会当即返回子进程结束状态值。
   子进程的结束状态值会由参数status 返回,而子进程的进程识别码也会一快返回。若是不在乎结束状态值,则参数status 能够设成NULL。参数pid 为欲等待的子进程识别码,其余数值意义以下:
   pid<-1 等待进程组识别码为pid 绝对值的任何子进程。
   pid=-1 等待任何子进程,至关于wait()。
   pid=0 等待进程组识别码与目前进程相同的任何子进程。
   pid>0 等待任何子进程识别码为pid 的子进程。
   参数option 能够为0 或下面的OR 组合:
   WNOHANG 若是没有任何已经结束的子进程则立刻返回,不予以等待。
   WUNTRACED 若是子进程进入暂停执行状况则立刻返回,但结束状态不予以理会。
   子进程的结束状态返回后存于status,底下有几个宏可判别结束状况:
   WIFEXITED(status)若是子进程正常结束则为非0值。
   WEXITSTATUS(status)取得子进程exit()返回的结束代码,通常会先用WIFEXITED 来判断是否正常结束才能使用此宏。
   WIFSIGNALED(status)若是子进程是由于信号而结束则此宏值为真。
   WTERMSIG(status) 取得子进程因信号而停止的信号代码,通常会先用WIFSIGNALED 来判断后才使用此宏。
   WIFSTOPPED(status) 若是子进程处于暂停执行状况则此宏值为真。通常只有使用WUNTRACED 时才会有此状况。
   WSTOPSIG(status) 取得引起子进程暂停的信号代码,通常会先用WIFSTOPPED 来判断后才使用此宏。
 
(5)进程通讯
如今linux使用的进程间通讯方式:
一、管道(pipe)和有名管道(FIFO)
1)管道(pipe)的介绍
A.管道是半双工的,数据只能向一个方向流动;须要双方通讯时,须要创建起两个管道
B.只能用于父子进程或者兄弟进程之间(具备亲缘关系的进程);
C.单独构成一种独立的文件系统:管道对于管道两端的进程而言,就是一个文件,但它不是普通的文件,它不属于某种文件系统,而是自立门户,单独构成一种文件系统,而且只存在与内存中。
D.数据的读出和写入:一个进程向管道中写的内容被管道另外一端的进程读出。写入的内容每次都添加在管道缓冲区的末尾,而且每次都是从缓冲区的头部读出数据。 
2)管道的建立
建立一个无名管道可使用系统调用 pipe()。它接受一个参数,也就是一个包括两个整数的数组。若是系统调用成功,此数组将包括管道使用的两个文件描述符。建立一个管道以后,通常状况下进程将产生一个新的进程。
系统调用: pipe();
原型:int pipe(int fd[2]);
返回值:若是系统调用成功,返回0。若是系统调用失败返回-1:
errno=EMFILE(没有空亲的文件描述符)        
 EMFILE(系统文件表已满)         
 EFAULT(fd数组无效)
注意:fd[0]用于读取管道,fd[1]用于写入管道。
3)有名管道的介绍
无名管道,因为没有名字,只能用于亲缘关系的进程间通讯.。为了克服这个缺点,提出了有名管道(FIFO)。
FIFO不一样于无名管道 之处在于它提供了一个路径名与之关联,以FIFO的文件形式存在于文件系统中,这样,即便与FIFO的建立进程不存在亲缘关系的进程,只要能够访问该路径,就可以彼此经过FIFO相互通讯,所以,经过FIFO不相关的进程也能交换数据。值的注意的是,FIFO严格遵循先进先出(first in first out),对管道及FIFO的读老是从开始处返回数据,对它们的写则把数据添加到末尾。它们不支持诸如lseek()等文件定位操做。
注意:有名管道的名字存在于文件系统中,内容存放在内存中

4)有名管道建立html

#include<sys/types.h>linux

#include<sys/stat.h>数组

int mkfifo(const char *pathname,mode_t mode);socket

返回:若成功则为0,若出错返回-1函数

一旦已经用mkfifo建立了一个FIFO,就可用open打开它。确实,通常的文件I/O函数(close,read,write,unlink等)均可用于FIFO。当打开一个FIFO时,非阻塞标(O_NONBLOCK)产生下列影响:post

A、在通常状况中(没有说明O_NONBLOCK),只读打开要阻塞到某个其余进程为写打开此FIFO。相似,为写而打开一个FIFO要阻塞到某个其余进程为读而打开它。ui

B、若是指一了O_NONBLOCK,则只读打开当即返回。可是,若是没有进程已经为读而打开一个FIFO,那么只写打开将出错返回,其errno是ENXIO。相似于管道,若写一个尚无进程为读而打开的FIFO,则产生信号SIGPIPE。若某个FIFO的最后一个写进程关闭了该FIFO,则将为该FIFO的读进程产生一个文件结束标志。url

FIFO相关出错信息:EACCES(无存取权限)EEXIST(指定文件不存在)
ENAMETOOLONG(路径名太长)
ENOENT(包含的目录不存在)
ENOSPC(文件系统余空间不足)
ENOTDIR(文件路径无效)
EROFS(指定的文件存在于只读文件系统中)
spa

管道是基于文件描述符的通讯方式。(因此会用到关于文件操做的一些函数)
使用方法能够参见 coding之路http://blog.sina.com.cn/s/blog_8713d5b20100tmod.html
二、信号(signal)
可详细参见下面大牛的博客:
 
(5)进程退出
http://blog.csdn.net/muge0913/article/details/7317580
 
本文参考内容:
六、http://blog.csdn.net/muge0913/article/details/7317580
相关文章
相关标签/搜索