Linux系统编程笔记—进程

程序与进程

什么是程序?

程序是静态的概念,例如,
gcc xxx.c -o a
磁盘中生成的a文件就叫做程序1

什么是进程?

进程则是动态的概念,程序的运行起来,系统中就多了一个进程

如何查看系统中有哪些进程

1,使用ps指令查看,配合grep来查找

ps -aux|grp xxx

2,使用top指令查看,类似windows任务管理器

什么是进程标识符?

每个进程都有一个非负整数表示的唯一ID,pid

如何查看pid号

#include <stdio.h>
#include <sys/types.h>
#include <unistd.h>
int main()
{
   pid_t pid
   pid = getpid();
   printf("%d\n",pid);
   return 0;
}

什么叫父进程,什么叫子进程

进程A创建了进程B,则称进程A为进程B的父进程,B叫做子进程

C程序的存储空间怎么分配

高地址:命令行参数和环境变量
低地址:栈

未初始化的数据
初始化的数据
正文//代码段

进程创建

使用fork()创建进程

在man 2函数中查看原型

       #include <unistd.h>
       pid_t fork(void);

fork函数调用成功,返回两次
返回值为0, 代表当前进程是子进程
返回值是正数,代表当前进程为父进程
调用失败,返回-1

使用fork函数的目的:
(1):一个父进程希望通过复制自己,使父子进程同时执行不同的代码段。
(2):一个进程要执行一个不同的程序。这对shell是常见的情况。在这种情况下,子进程从fork返回后立即调用exec

总结:fork调用一次返回两次,子进程返回0,父进程返回子进程的进程id,因为一个进程的子进程可以有多个,并且没有一个函数会使一个进程获得所以子进程的进程id。fork使子进程得到返回值为0,因为一个异常只会有一个父进程,所以子进程总是可以调用getpid()以获得其父进程的进程id(进程id 0总是由内核交换进程使用,所以一个子进程的进程id不可能为0)。子进程是父进程的副本,子进程获得父进程的数据空间,堆栈的副本,不共享存储空间部分,父子进程共享正文部分。

使用vfork()创建进程

同fork()创建进程区别:
一:vfork直接使用父进程存储空间,不拷贝。
二:vfork保证子进程先运行,当子进程调用exit退出之后,父进程才执行

进程退出

正常退出

1,main函数调用return
2,进程调用exit,标准c库
3,进程调用_exit或者_Exit(),属于系统调用
4,进程最后一个线程返回
5,最后一个线程调用pthread_exit

异常退出

1,调用abort
2,当进程收到某些信号时,如ctrl+c
3,最后一个线程对取消请求作出响应

不管进程如何终止,都会执行一段代码,为相应进程关闭所有打开描述符,释放他们所使用的存储器

父进程等待子进程退出,并收集子进程的退出状态
子进程退出状态不被收集,变成僵尸进程

wait()函数

函数原型为

       #include <sys/types.h>
       #include <sys/wait.h>
       pid_t wait(int *status);
       pid_t waitpid(pid_t pid, int *status, int options);
       int waitid(idtype_t idtype, id_t id, siginfo_t *infop, int options);

wait()解析:
如果其所有子进程都还在运行,则阻塞
如果一个子进程已终止,正在等待父进程获取其终止状态,则取得该子进程的终止状态立即返回
如果它没有任何子进程,则立即出错返回

#include <stdio.h>
#include <sys/types.h>
#include <unistd.h>
int main()
{
   int cnt = 0;
   int status = 10;
   pid = fork();
   if(pid > 0)
   {   
       wait(&status);
       printf("child quit, child status = %d\n",WEXITSTATUS(status));
       while(1){
              printf("cnt = %d\n",cnt);
              printf("this is father print, pid = %d\n",getpid());
              sleep(1);
       }
   }
   else if(pid == 0){
   while(1){
           printf("this is child print,pid = %d\n",getpid());
           sleep(1);
           cnt++;
           if(cnt == 5){
           exit(3);
           }
      }
   }
   return 0;
}

WEXITSTATUS(status):取子进程传送给exit, _exit, 或_Exit参数的低8位

父进程如果不等待子进程退出,在子进程之前就结束了自己的“生命”,此时子进程叫做孤儿进程1
Linux避免系统存在过多孤儿进程,init进程收留孤儿进程,变成孤儿进程的父进程

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值