进程概念

程序:为了执行特定任务的一系列指令的有序集合

单道程序设计  时钟中断  ——> 进程
多道程序设计  分时系统

1.硬件中断技术的出现,进而软件上有了分时系统,时间片轮转
2.进程:从用户角度看,进程就是程序的一次动态执行过程
3.从操作系统(内核)的角度看,
    (1)进程是操作系统分配内存,cpu时间片等系统资源的基本单位(硬盘不算)
    (2)每个进程有自己独立的虚拟地址空间和进程状态
    (3)进程是分配资源的最小单位
4.进程是程序的一次执行过程,需要保存进程的现场信息,这些信息需要一个数据结构来保存,在c语言中用结构体,我们将这个结构称为PCB(process control block)。
5.PCB是操作系统感知一个进程存在的重要数据结构。
6.程序:代码段+数据段。
7.进程:代码段+数据段+堆栈+PCB
pc:下一条指令的地址
esp:栈顶指针
ebp:基址
PCB将代码和有效数据的粘合在一起。
进程和进程的区别:
1).进程是动态的,程序是静态的。
2).进程是短暂的,程序是永久的。
3).进程有PCB
4).一个进程只能对应一个程序,一个程序可以对应多个进程。
(https://img-blog.csdn.net/20180412182839582?watermark/2/text
/aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L2xjNTc4NjI2
/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70)

awk ‘{print }’filena
查看进程信息:ps aux  (睡眠态)  ps aux |grep aplay| grep -v grep | awk ‘{print $2}’
kill -l
状态变迁:
三态
liunx七态
ps查看进程状态
ps aux  /ps -ef

(https://img-blog.csdn.net/201804121835026?watermark/2/text/
aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L2xjNTc4NjI2
/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70)

liunx对应的PCB数据结构:task_struct 保存以下内容
进程标识符
进程状态
进程优先级
各种时间信息
进程间通信信息
内存使用情况
寄存器的信息(也叫保存现场)

内存使用情况:
https://img-blog.csdn.net/
20180412183713534?watermark/2/text/
aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L2xjNTc4NjI2
/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70)

进程标识符:
操作系统会给每个进程分配一个独一无二的编号。
编号的范围:[2,cat /proc/sys/kernel/pid_max]
0是内核进程
0号进程启动1(init)号进程。
swap分区。
创建进程的一般过程:
给新建的进程分配一个进程标识符,在内核中创建PCB,
复制父进程的环境。(新的进程为子进程)
给子进程分配资源,栈,堆,代码,数据等。
拷贝父进程的地址空间内容到子进程的地址空间
将进程置为就绪态,放到就绪队列。
在proc 的下:cat maps  查看进程分配情况。
创建子进程:
pid _t fork(void)
    父进程返回进程ID,子进程返回0。
附加:
    错误处理
    1.若干个if else
    2.定义一个errno,所有的系统调用出错都返回-1,然     后将错误编号记录到errno中
     通过strerror得到错误编号对应的描述
获得子进程ID
pid_t getpid(void)
获得父进程ID
pid_t getppif(void)
fork的注意点:
1.fork之后,父子进程交替运行
2.如果父进程死亡,子进程活着,叫孤儿进程。孤儿进程托管给1号进程,1号进程也叫孤儿院。
3.如果父进程活着,子进程死亡,子进程就是一个僵尸进程。僵尸进程会占用少量系统资源。僵尸进程是有害的。
弄死进程的方法:
1.ctrl + c   2.kill  pid  3.kill -9 pid(杀人不眨眼的)  kill 不能杀死僵尸进程
进程被虚拟文件:
进程优先级:/proc/pid
1.nice -n 优先级  程序名(优先级 -20——192.renic 优先级 -p 进程名
3.top     shift+>/< 翻屏  r pid
写时拷贝:
没有必要全部拷贝一份,父子进程什么时候修改,什么时候拷贝一份出来。称之为写时拷贝。
vfork 第二个创建子进程函数:
pid_t pid = vfork()
特点:
    1.父进程阻塞,直到子进程运行完毕。
    2.就算写时,也不拷贝
    3.必须使用exit/exec
    4.每个系统堆=对vfork的实现或多或少都有问题,不要使用
traceroute www.baidu.com  
销毁进程的过程:
    1.释放资源。(内存,文件等等)
    2.记账信息。
    3.将进程设置为僵尸状态。
    4.转存储调度。(将CPU让给需要使用的进程)
进程退出的方法:
    正常退出:
        1.main函数退出。
        2.exit
    异常退出:
        1.ctrl + c
        2.abort(函数)
        3.kill
    所有不正常死亡都是由信号引起。
    ![这里写图片描述](https://img-blog.csdn.net/20180412184022734?watermark/2/text/aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L2xjNTc4NjI2/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70)
退出时执行注册函数
int on_exit(void (*function)(int , void *), void *arg);
int on_exit(void (*function)(int , 是退出码
void *), 
void *arg) //退出处理函数参数

等待进程:
pid_t wait(int *status);
//阻塞,直到有子进程退出才返回。status参数会得到子进程是如何死亡的。
//返回值:被回收的子进程ID,出错,返回-1.
WIFEXITED(status) 如果正常退出,返回真
WEXITSTATUS(status) 如果正常退出,得到退出码
WIFSIGNALED(status) 如果信号被打断,返回真
WTERMSIG(status) 如果是被信号打断,得到信号
pid_t waitpid(pid_t pid, int *status, int options);
pid_t waitpid(pid_t pid, 
int *status, //
int options);// 0  WNOHANG
    pid > 0;等待进程id等于pid的子进程死亡
    pid = 0;调用者进程所在进程组的任何一个子进程死亡
pid = -1;等待任何一个子进程死亡
    pid < -1;|pid|进程组的任何一个子进程死亡
进程空间交换:
int execvp(const char *file, char *const argv[]);(替换4G空间)
    int execvp(const char *file, //可执行程序名字
    char *const argv[]); //main函数的参数
exic不创建新进程、PCB,进程id不会变。
5个函数:
1. int execl(const char *path, const char *arg, ...);
2. int execlp(const char *file, const char *arg;
3. int execle(const char *path, const char *arg,
              ..., char * const envp[]);
4. int execv(const char *path, char *const argv[]);
5. int execvp(const char *file, char *const argv[]);
v:vector
l:list
p:path
e:environ
补充:
    环境变量:
        定义变量: name=value  等号左右不能有空格。是一个         本地变量,只能在当前进程里使用。
        删除变量:unset name
    将本地变量转化为环境变量:
        export name
    本地变量只能在当前进程使用,环境变量可以在当前进程及子 进程使用。
pstree: 可以将进程的树状结构打印出来。
问题:
    1.系统有哪些环境变量
        env 查看,history 查看历史命令
    2.将自己定义的环境变量放在哪里?终端打开就存在该环境变    量。
        登陆shell之前,会执行 ~/.bash_profile 文件,本用户           的配  置/etc/profile 整个系统所有用户的配置。
程序中如何操作环境变量:
    设置环境变量:int putenv(const char *str)str 的格                        "name=value"
    读取环境变量的值:
    char *getenv(const char *name)获取一个环境变量。
    main函数的第三个参数 int main(int a, char*b[], char*c)  获取所有的环境变量。
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值