进程控制

进程创建:有  pid_t   fork(void)  pid_t  vfork()  两个函数

fork():它的返回值:子进程中返回0,父进程中返回进程id,出错返回-1。

进程调用fork,当进程转移到内核中的fork代码后,内核需要:

 1)分配新的内存块和内核数据结构给子进程。

 2)将父进程的部分数据结构内容拷贝给子进程

 3)添加子进程到系统的进程列表中

 4)fork返回,开始调度器调度。

这里要提到写时拷贝:通常,父子进程代码共享,数据也是共享的,当任意一方试图写入,便以写时拷贝的方式各自一份副本。

用fork()函数创建一个子进程

  1 #include<stdio.h>
  2 #include<unistd.h>
  3 #include<stdlib.h>
  4 
  5 int a=100;
  6 
  7 int main()
  8 {
  9         pid_t pid;
 10         pid=fork();
 11         if(pid==-1){
 12                 perror("fork");
 13                 exit(1);
 14         }
 15         if(pid==0){
 16                 a=200;
 17                 printf("i am child %d \n",a);
 18                 exit(0);
 19         }else{
 20                 sleep(2);
 21                 printf("i am parent %d \n",a);
 22         }
 23         return 0;
 24 }
~       

 

运行结果:

i am child  200 
i am parent 100

可见子进程中不会改变父进程中的变量值。

pid_t  vfork(void)中子进程可以改变父进程中变量的值,以为子进程在父进程的地址空间中运行。

      1 #include<stdio.h>
      2 #include<unistd.h>
      3 #include<stdlib.h>
      4 
      5 int a=100;
      6 
      7 int main()
      8 {
      9         pid_t pid;
     10         pid=vfork();
     11         if(pid==-1){
     12                 perror("fork");
     13                 exit(1);
     14         }
     15         if(pid==0){
     16                 a=200;
     17                 printf("i am child %d \n",a);
     18                 exit(0);
     19         }else{
     20                 sleep(2);
     21                 printf("i am parent %d \n",a);
     22         }
     23         return 0;
     24 }
~        

 

运行结果:

i am child  200 
i am parent 200

调整进程的优先级:  [-20,19] 优先级值越小,优先级越高
                                      nice -n 优先级 程序名
                                      renice 优先级 -p pid

进程终止

正常终止:① 从main函数中退出 ②调用 exit ③_exit  

 exit函数在程序退出时关闭所有打开的流,并刷新缓存,_exit不会刷新缓存

异常退出:1.ctrl+c
                    2.abort();
                    3.kill pid   让进程自己去死
                                                     killall  进程名   全部杀死  例 killall a.out
                        atexit(void fun(void))  //注册退出处理程序

return退出

return是一种更常见的退出进程的方式。执行return n等同于执行exit(n),因为调用main的运行时函数会将main的返回值当做exit的参数。

进程等待

wait方法

  pid_t wait(int *status)

返回值:成功返回被等待进程的pid,失败返回-1

参数:输出型参数,获取子进程的退出状态,不关心可以设置为NULL。

waitpid方法

pid_t  waitpid(pid_t  pid, int  *status, int  options)

参数:

     pid:

    pid= -1,等待任意一个子进程。与wait等效。

    pid>0:本进程的子进程
    pid=0:调用者进程所在进程组的任何一个子进程死亡
    pid<-1:|pid|进程组的任何一个子进程死亡

返回值:

   正常返回时waitpid返回收集到的子进程的进程id;

   如果设置了选项WONHANG,若没有子进程需要回收则直接返回0;

   如果调用中出错,则返回-1,errno会被设置成相应的错误码。

●如果子进程已经退出,调用wait/waitpid时会立即返回并且释放资源,获得子进程的退出信息。

●如果在任意时刻调用wait/waitpid,子进程存在且正常运行,则进程可能阻塞。

●如不存在子进程,则立即出错返回。

 

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值