step4 . day5 进程与进程的创建

1.什么是进程:进程是系统中正在运行的一个程序,程序一旦运行就是进程,区别于程序的静止状态,进程是一个动态概念,包含了程序运行时需求的资源总和

2.进程的分类:交互进程、批处理进程、守护进程(不依赖shell的后台进程)

3.进程的状态:运行态、停止态、不可中断等待、可中断等待、僵死态

4.进程相关命令

ps -ef  查看所有进程

ps -elf  / ps -aux

PID 进程号

PPID 父进程号

CMD 进程的名子

NI nice值 优先级

ps -ef | grep ./a.out

top  动态显示所有进程  

nice  改变进程的优先级 -20~19  值越大优先级越低

renice 动态改变进程优先级

ctrl +z 把运行的前台进程变为停止态后台进程

bg 把后台进程变为运行态

fg 把后台进程变为前台

jobs 查看所有后台程序

如果有多个,加序号 如:fg 1,bg 2

5.进程创建函数fork(),一个函数两个返回值,父进程返回值为子进程ID,子进程返回值为0,参见man手册

特点:

1.父子有相同的代码段和数据段,资源是一样的

2)逻辑地址空间独立,物理有些是共享的。使用写时copy技术节省系统资源

3)父或子进程结束后,活着的进程状态。

父先死 子变孤儿 被init收养

子先死 子变僵尸,需f要父进程收尸

4)父子进程执行顺序不确定,由操作系统调度来确定。 

6. 退出应用程序,exit结束程序前刷新缓冲区,_exit不刷新缓冲区

7.wait 和 waitpid    如果没有子进程退出,等待,如果有,则返回子进程的pid号,参数status传出退出时候的状态值

8.exec函数族 和system函数,用于在进程中执行另一个系统命令,system函数不会替换使用函数进程的内容,exec会替换执行进程的执行内容

9代码demo  创建连串子进程(通过fork的返回值判断是否继续创建子进程)


#include<stdio.h>
#include <unistd.h>


int main(int argc, const char *argv[])
{
pid_t t;
int i;
for(i = 0;i < 5;i++){
t = fork();
if(t != 0)
break;
}
if(t<0){
perror("fork");
return -1;
}else if(t = 0){
printf("I am subprocess\n");
while(1) sleep(1);
}else{
printf("I am parent process\n");
while(1) sleep(1);
}
return 0;

}

2.使用进程模拟shell(使用字符串裁切或者system都行)


#include <stdio.h>
#include <sys/types.h>
#include <sys/wait.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>

int main(int argc, const char *argv[])
{
pid_t t,t1;
int status,n=0;
char buf[16],*result;
char buf1[16];
char arg[8][8];
while(1){

t = fork();
if(t<0){
perror("fork");
return -1;
}else if(t == 0){
execlp("config.sh","config.sh",NULL);   //自己写了一个简单的shell脚本,配置了一下环境变量,省去了多次打印路径的麻烦
exit(0);

}else{
printf(" ");
waitpid(t,&status,0);
}

fgets(buf,16,stdin);
strcpy(buf1,buf);

result = strtok(buf," ");
strcpy(arg[0],result);
n=1;
while(result != NULL){
strcpy(arg[n],result);
// printf("%s\n",arg[n]);
n++;
result = strtok(NULL," ");
}

t1 = fork();
if(t1<0){
perror("fork");
return -1;
}else if(t1 == 0){
system(buf1);
// printf("----------------\n");
//execlp(arg[0],arg);
//arg[3],arg[4],arg[5],arg[6],arg[7],NULL);
exit(0);

}else{
waitpid(t1,&status,0);
}


}

return 0;
}

2.守护进程

创建顺序:

1)创建一个子进程,同时父进程退出,目的是为了让子进程成为后台进程
2)设置setsid 设置会话组,把子进程变为会话组组长,独立门户,跟shell,界面等父进程脱离干系
3)改变工作目录,到一个稳定的目录下面chdir("/")
4)  umask(0),改变文件的屏蔽符,防止改变守护进程的文件权限
5)关闭从父进程继承来的文件描述符

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

int main(){
pid_t pid;
pid = fork();
if(pid<0){
perror("fork");
return 0;
}else if(pid>0){
exit(0);
}
//下面都是子进程执行的代码
if(setsid()==-1){
perror("setsid");
exit(0);
}
chdir("/");
if(umask(0)<0){
perror("unmask");
exit(0);
}
int i;
//printf("getdtablesize()=%d\n",getdtablesize());
for(i=0;i<getdtablesize();i++)
{
// printf("i=%d\n",i);
close(i);
}

while(1){
sleep(1);
}



}

猜你喜欢

转载自www.cnblogs.com/huiji12321/p/11318394.html