进程控制

1、什么是进程?

(1)概念:进程是正在执行的程序的实例,是linux的基本调度单位;程序写好之后,放在内存,程序在运行时,进程就创建了,通俗的说,程序是“死的”,进程是“活的”;
(2)组成元素:
1)进程的当前上下文(context),是进程当前的执行状态
2)当前执行目录
3)访问文件和目录
4)访问权限
5)内存和其它分配给进程的系统资源
(3)进程标识符pid
1)父子进程:

父进程标识符:ppid
子进程标识符 :pid
//均为非零的整数

2)一个PID唯一标识一个进程
3)祖先进程的进程号为1,叫做init进程,它是linux启动后第一个执行的进程,init引导系统启动守护进程,并且运行必要的程序
4)PID的用法:
《1》是创建唯一的文件或者目录名
《2》把PID写入日志文件,作为日志消息的一部分

二、如何创建进程?

(1)system:用于调用shell,执行一个指定的命令;
(2)fork:用于创建一个新的进程, 该进程几乎是当前进程的一个完全拷贝;
(3)execve可以在进程中用另外的进程来替换当前运行的进程;
1、得到PID的方法:

  1 #include<stdio.h>
  2 #include<stdlib.h>
  3 #include<unistd.h>
  4 #include<sys/types.h>
  5
  6 int  main()
  7 {
  8     //test pid****************
  9         printf("PID = %d\n",getpid() );
 10         printf("PPID = %d\n",getppid() );
 11         return 0;
 12 }


2、察看最大进程数

$cd /proc
$cd sys
$cd kernel
$cat pid_max

如下所示:

3、UID用户号

  1 #include<stdio.h>
  2 #include<stdlib.h>
  3 #include<unistd.h>
  4 #include<sys/types.h>
  5 #include<pwd.h>
  6 int main()
  7 {
  8  //**********test getlogin *************
  9     char* login = getlogin();
 10      struct passwd *ps = getpwnam(login);
 11      printf("user name = %s\n",ps->pw_name);
 12      printf("uid = %d \n",ps->pw_uid);
 13      printf("home dir = %s \n",ps->pw_dir);
 14     return 0;
 15 }   
 //getlogin()函数返回执行程序的用户登录名和用户号

三、fork()函数

(1)特性:

pid_t fork(void);

fork( )执行后:
成功:向父进程返回子进程的PID,并向子进程返回0,这也就意味着fork( )一次调用,两次返回;
失败:向父进程返回-1,并且不创建子进程
fork( )创建的新进程是和父进程一样的副本;
fork( )创建出来的父子进程之间是异步的,没有依赖性;
(2)创建:
(1)无法预计父进程在子进程之前还是之后运行,它们的执行是无序的,是异步的;
(2)异步就意味着父子进程代码无依赖性
(3)fork( )可能失败,原因是因为系统上已经运行了太多的进程,超过了它所允许的最大进程数;
(4)fork( )过程包括将父进程全部内存映像给子进程,过程缓慢
(5)调用vfork( )也创建新的进程,但不产生父进程的副本
[linux已经使用了写时复制技术,因此linu的vfork( )和UNIX中的vfork( )一样快]

四、execve()函数

**(1)特性:**execve启动一个新程序,替换原有进程,故被执行的进程PID不变,是用被执行的程序完全替换了调用进程的映像

int execve(const char*path,const char*argv,char* const envp[]);
//const char*path: 要执行文件的完整路径
//const char*argv:传递给程序完整的参数列表
//char* const envp[]:指向execed程序的环境指针,可设为NULL

ls的实现

 #include<stdio.h>
  2 #include<stdlib.h>
  3 #include<sys/types.h>
  4 #include<unistd.h>
  5 #include<pwd.h>
 6 int main()
 44 {
 45     char *args[] = {"bin/ls","-l",NULL};
 46     execve("/bin/ls",args,NULL);//执行到这里,程序结束
 47     printf("end\n");
 48     return 0;
 49 }

1、执行 ./fork结果

2、执行 ls -l结果

五、比较:

system:创建两个不同的进程,进程间相互独立,pid不同
fork:创建两个一样的进程,自进程是父进程的一个副本,但pid不一样
execve:创建一个进程,替换原来进程,pid不变

wait( )和waitpid( )

pid_t wait(int* status);
pid_t waitpid(pid_t pid,int * status,int options);
//pid_t pid:等待进程的PID 
//int * status: 保存子进程的退出状态
//int options

pid的取值:

-1等待任何PGID等于PID的绝对值子进程
1等待任何子进程
0等待任何PGID等于调用进程的子进程
0等待PID等于pid的子进程

  1 #include<stdio.h>
  2 #include<stdlib.h>
  3 #include<sys/types.h>
  4 #include<unistd.h>
  5 #include<pwd.h>
  6
  7 int main()
  8 {
  9     pid_t pid = fork();
 10     int status;
 11     if(pid == -1)
 12     {
 13         printf("fork filed\n");
 14         return 0;
 15     }
 16     if(pid == 0)
 17          {
 18              printf("child process start\n");
 19              sleep(2);
 20              printf("child process end\n");
 21              return 100;
 22          }
23     else
 24     {
 25         printf("parent process start\n");
 26         wait(&status);
 //出错一:
 27 //   printf("status = %d\n",status);//打印status要借助WEXITSTATUS( )
 //正确调用:
 28     printf("status = %d\n",WEXITSTATUS(status) );
 //显示status的状态,必须使用WEXITSTATUS函数
 29 
 30         printf("parent process end\n");
 31         return 0;
 32     }

出错一的结果:

正确调用结果:

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值