Linux 进程控制

来源:互联网 发布:生死狙击刷枪刷枪软件 编辑:程序博客网 时间:2024/04/30 08:06

Linux进程控制
程序和进程
程序(program)是存放在磁盘文件中的可执行文件。
进程和进程ID
程序的执行实例被称为进程(process)也可以称为任务。某些操作系统
用任务表示正被执行的程序。
每个Linux进程都一定有一个唯一的数字标识符,称为进程ID(process
ID)。进程ID总是一非负整数(大于1的)。

 

Linux下的进程结构
Linux系统是一个多进程的系统,进程之间具有并行性、互不干扰的特点
。Linux中进程包含3个段,分别为“代码段(程序的流程)”,“数据段(系统使用有关重要的数据——全局变量和静态变量)”和“堆栈段(存放基本的临时变量)”。
哪些变量放在堆中,哪些变量放在栈中?
静态变量或是全局变量放在堆中。
子函数入口的临时变量或是局部变量放在栈中。

 

“数据段”存放全局变量、常数以及动态数据分配的空间(malloc函数取得的空间);“代码段”存放程序代码;“堆栈段”存放子程序的返回地址、子程序的参数以及程序的局部变量

 

init进程
A、进程ID为1通常是init进程,在自举过程结束时由内核调用。
B、init进程绝不会终止。
C、它是一个普通的用户进程(与交换进程不同,它不是内核中的系统进
程),但是它以超级用户特权运行。


获取进程标识
#include<sys/types.h>
#include<unistd.h>
pid_t getpid(void);返回:调用进程的进程ID
pid_t getppid(void);返回:调用进程的父进程ID
uid_t getuid(void);返回:调用进程的实际用户ID
uid_t geteuie(void);返回:调用进程的有效用户ID
gid_t getgid(void);返回:调用进程的实际组ID
gid_t getegid(void);返回:调用进程的有效组ID

 

fork()函数
表示由当前进程生成一个进程出来
#include<sys/types.h>
#include<unistd.h>
pid_t fork(void);
返回:子进程中为0,父进程中为子进程ID,出错为-1
返回值有两个,大于0代表父进程中,等于0子进程中
创建
由fork创建的新进程被称为子进程(child process)。
该函数被调用一次,但返回两次。两次返回的区别是子进程的返回值是0
,而父进程的返回值则是子进程的进程ID。
一般来说,在fork之后是父进各程先执行还是子进程先执行是不确定的
。这取决于内核所使用的调度算法。

使用fork函数得到的子进程是父进程的处继承了整个进程的地址空间,包括:进程上下文、进程堆栈、内存信息、打开的文件描述符、信号控制设置、进程优先级、进程组号、当前工作目录、根目录、资源限制、控制终端等。

 

父、子进程之间的区别是:
A、fork的返回值;
B、进程ID、不同的父进程ID;
C、子进程的tms_utime,tms_stime,tms_cutime以及tms_ustime设置为0
;运行时间,产生时间,调整时间,u代表毫秒数,s代表秒数
D、父进程设置的锁,子进程不继承;
E、子进程的未决告警被清除;
F、子进程的未决信号集设置为空集。

 

source Insight软件
fork.c
#include<sys/types.h>
#include<unistd.h>
#include<stdio.h>
#include<stdlib.h>

int main(void)
{
pid_t result;
result=fork();
if(result==1){
   perror("fork");
   exit;
}
else if(result==0){
printf("The return value if %d/nIn child process!!/nMyPID is %
d/n",result,getpid());
}else {
printf("The return value is %d/nIn father process!!/nMy PID is
%d/n",result,getpid());
}
}

vfork()函数
vfork函数的调用序列和返回值与fork相同,但两者的语义不同。现在很
多的实现并不做一个父进程数据段和堆的完全拷贝,因为在fork之后经常跟随着exec。作为替代,使用了在写时复制(copy-on-Write,COW)的技术。这些区域由父、子进程共享,而且内核将它们的存取许可权改变为只读的。如果有进程试图修改这些区域,则内核为有关部分,典型的是虚存系统中的“页”,做一个拷贝。如:uclinux中的进程创建。

 

 

exec函数
在用fork函数创建了子进程以后,子进程往往要调用一种exec函数以执
行另一个程序。
当进程调用一种exec函数时,该进程完全由新程序代换,而新程序则从
其main函数开始执行。因为调用exec并不创建新进程,所以前后的进程ID并未改变。exec只是用另一个新程序替换了当前进程的正文、数据、堆和栈段。
#include<unistd.h>
int execl(const char * pathname,const char * arg0,..../*(char
*) 0 */);
int execv(const char * pathname, char *const a rgv[]);
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* pathname,const char * arg0 ,.../*(char
*)0*/);
int execvp(const char * pahtname, char *const argv[]);
六个函数返回:若出现则为-1,若成功则不返回
说明:
(1)名字中带有P的(execlp,execvp);名字中带P的exec函数以一个
完整的路径名字当作第一个参数,而其它四个参数将以可执行文件的名字作为参数,他们会在环境变量PATH指定的路径中寻找可执行文件。
(2)名字中带有l的(execl,execlp,execle)):表示命令行参数使用
list(列表)的形式传递,以一个NULL结尾。
(3)名字中带有V的(execv,execvp,execve):表示命名行参数以
vertor(向量数组)的形式传递。
(4) 名字中带有e的(execve,execle):表示在执行命令时,使用参
数envp中指定的环境变量。

实例代码如下:

execlp.c  
#include<unistd.h>
#include<stdio.h>
#include<stdlib.h>

int main(){
if(fork()==0){
if(execlp("ps","ps","-ef",NULL)<0)
 perror("execlp error!");
}
return 0;
}

execl.c
#include<unistd.h>
#include<stdio.h>
#include<stdlib.h>

int main(){
if(fork()==0){
if(execl("/bin/ps","ps","-ef",NULL)<0)
 perror("execl error!");
}
return 0;
}

execle.c
#include<unistd.h>
#include<stdio.h>
#include<stdlib.h>
int main(){
char *envp[]={"PATH=/tmp","USER=xuepeng",NULL};
if(fork()==0){
if(ececle("/bin/env","env",NULL,envp)<0)
perror("execle error!");
}
return 0;
}

 

 

 

 

 

 

 

 

原创粉丝点击