狐狸梦见乌鸦

当坚持成为一种习惯,目标将不在遥远```
  博客园  :: 首页  :: 新随笔  :: 联系 :: 订阅 订阅  :: 管理

进程---学习笔记

Posted on 2012-01-02 11:12  灬啊U  阅读(214)  评论(0编辑  收藏  举报

进程:

什么是进程?为什么要学进程?

阻塞的概念…………………….标准IO流中等待获取信息,,,,等待就是阻塞!

 

嵌入式设备---------数据的采集

如何创建进程??

 

程序:是静态的,程序的运行-à进程。

进程----它是一个程序的实例;  进程--à①---à②<-----线程--à调度  

①资源的分配      进程是程序执行和资源分配的最小单位

②进程描述符(tast_struct)  结构体----用来描述一个进程

sizeof(tast_struct) -----1.7k

③线程   (内核调度的最小单位)  内核怎么执行它?  current 指向当前需要执行的进程。。。。。

④调度

 

进程                                       程序

文本段 text                                二进制指令集的结合(文本段)

数据段data                                文本段text------数据段(全局段)

堆栈段stack(局部变量,回调关系)文本段—自读数据,而数据段为可读写数据

 

数据段:存放的是全局变量、常数以及动态分配数据分配的空间(malloc)

文本段:存放程序中的代码。

堆栈段:存放的是函数返回的地址,函数的参数以及程序中的局部变量。

进程ID

task_struct 中存在一个进程号PID,为用户提供找到tast_struct这结构体,另外还有一个parent指向tast_struct,不能给用户和直接操作,所以又提供另一PPID父进程号。。。。

 

ps  -ef  查看进程号

pid = getpid()对于每个进程来说都是唯一的。。。    ppid = getppid()  

init   一号进程,这个一号进程能够获得什么东西呢???孤儿进程的回收站

init是内核启动到最后阶段,自动执行的。。。。。init创建一个tast_struct去执行其它程序。。。

 

linux系统中的进程类型:

① 交互式进程:由shell控制和运行的。。

②批量出路进程   很少使用

③守护进程:该程序在后台运行,其次它与所有终端都无关,一般在linux启动时开始执行,系统关闭的时候才结束。。。

 

进程的运行状态:

①运行态:此时进程或者在运行或在准备运行

②等待态:

 可中断------不可中断

③停止态:进程终止。。。。。。debug时。。。。

死亡态:也叫僵尸态。子进程退出,但是父进程没退出,此时的子进程就是僵尸态。。。子进程的状态不会被系统回收,它需要父进程回收。。。注意:父进程必须及时注意回收子进程,以免内存泄露

 

 

进程的模式:

①3G 大小的 用户空间   用户模式  只能通过系统调用(system  call)来操作内核

②1G 大小的 内核空间   内核模式   物理地址映射到虚拟空间的部分

 

 

6.32         位操作系统 拥有4G寻址空间

 

7.进程的一些命令:

ps  查看系统中的进程  -aux  显示详细信息   -ef 

top  和 资源管理器相似。。。。。一直刷新显示不同的状态

注意:pstop  依赖与/proc目录(proc文件系统),因为/proc是挂载点,掉电丢失。。。。/proc中每个数字都为一个进程号

 

nice (需要权限)按用户指定某种优先级来运行进程   nice  --20 ./a.out  &     %100独占CPU(优先级的概念:高优先级的任务分配更多的时间片。。。。    抢占 :重新分配时间片  )

renice 改变正在运行进程的优先级   renice  -19  PID号

kill   向一个进程发送一个信号    kill  -l 可看到这些信号  

例如:kill  -9  PID号   向PID号的进程发送9这一信号(SIGKILL)

history  | grep  renice  查看历史renice信息

 

 bg  将挂起(ctrl + z)的进程放到后台执行

 fg   将最后挂起的进程重新放到前台运行

 

8. 创建一个进程:  目的,让两个人进程间有血缘关系,执行同一程序中的不同的代码部分。。。

fork() 没有参数。。。

注意:返回值,{-1  失败, 0  或者 > 0  成功}

调用一个fork()----即创建了2个进程。。。。   clone出一个父进程的子进程,即2相同的进程,执行相同的代码。fork执行的过程中即已经变为2个进程,同时向父进程返回一个大于0的号,向子进程返回一个0.。。。。。。。(父进程为什么要返回 > 0? 因为父进程有多个儿子。。。)

if(pid = = fork()<0)   理论上子进程先执行

       exit -1;

if (pid  >  0)

       ppid; // 父进程

else if (pid == 0)

    pid; // 子进程

 

9.vfork()与fork()的不同之处:数据共享----执行顺序------退出

vfork不拷贝父进程的任何资源,但和父进程共享资源。。。。。

vfork之后父进程停止,而先执行子进程,子进程执行完成后且调用exec或者exit(),然后才执行父进程。。。

即用vfork的主要目的是调用exec

子进程必须调用exec 或者exit0)。。如果没有,则程序执行出现异常

 

当今的fork是写拷贝技术。。。。。。。。写拷贝技术????当数据需要用时才拷贝,否则不拷贝。。这样的好处就是,避免了vfork的数据共享,也避免了fork的全拷贝。。。。。。

 

10.exec函数族(有6个)

shell脚本--------C语言中 

函数的作用:把当前进程作为一个容器,然后将另外一个程序的内容填充。。。。。所以,exec后的程序将不能执行。。。

 

注意:在使用exec函数族时,一定要加上错误判断语句。。。。。

 

if execl”/bin/ls”,”ls”,”-l”,NULL< 0  //  NULL是一个类似哨兵,必须有这个参数

{

       perror(“execl\n”);

return -1;

}

11.完善man帮助包 。。。。有些man不出来

sudo  apt-get  install  manpages-posix-dev

 

12.exit(status)  #include<stdlib.h> 和 _exit(status)   #include <unistd.h>

status是一个整型的参数,可以利用这个参数传递进程结束的状态。通常0表示正常结束;其他的数值表示出现错误。。。。

 exit和_exit()的区别:

_exit()函数直接使进程停止运行,清除其使用的内存空间,并销毁其再内核中的各种数据结构;

exit()函数则在这些基础上作了包装,在调用exit系统之前要检查文件的打开情况,把文件缓冲区中的内容写回文件,即“清理I/O缓冲”。。。注意换行‘\n’也会引起I/O的清理工作。。。。。

使用_exit退出,上一语句必须有’\n’换行符,才能够打印出语句。。。。

 

13.wait和waitpid

wait函数:只能父进程调用。。。。回收子进程的状态

waitpid 主要功能:回收子进程的状态。。。。   wait  是waitpid的一个特例。。。。。。

pid_t  waitpid(pid,status,options)

参数:pid > 0,等待进程ID等于pid的子进程(指定ID)

      pid = -1 等待任意一个子进程 (wait == waitpid(-1,status,0))

      pid = 0 

      pid < -1

      WNOHANG:

      WUNHACED:

 

与进程相关的概念:

会话:每个用户登录一次,则开打一个会话

进程组:在终端上执行,则产生一个进程组

进程:

 

14.守护进程 dacmon  主要运用在网络服务中使用

一般是一些服务,常在系统启动时开始运行,系统关闭时终止。。

一般运行在后台,脱离终端,它不属于

ps  -ef 查看。。。。名字后面带个d,都是守护进程

创建守护进程的步骤:

创建子进程,父进程退出

(第一步结束之后,子进程就在形式上与控制终端脱离,又由于负进程已经先于子进程退出,子进程变成了孤儿进程)

pid = fork();

if (pid >0)

   exit(0);

在子进程中创建新的回话

进程组是一个或者个进程的集合,进程组由进程组ID来唯一标识。没给进程组都有一个组长进程,进程组ID组长进程的进程号)

   (会话组是一个或者多个进程组的集合。。。在子进程中创建新的会话,)

setsid();// 创建一个新的会话,并使得当前进程称为新会话组的组长。

       //setsid函数能够使进程完全独立出来,从而脱离所有其他进程的控制。。。。。

改变工作的目录为目录

chdir(“/”);

重设文件权限掩码

umask(0);

关闭文件描述符

(新的进程会从父进程那里继承所有已经打开的文件。。。再创建完成新的会话之后,守护进程已经脱离任何控制终端,应当关闭用不到的文件)

close(fd); 

 

 

 

 

实验例程:

查看系统环境变量

#include <stdio.h>

int main(int argc, char **argv, char **envp)

{

  int i = 0;

  while(envp[i]  != NULL)

  {

      printf("%s\n", envp[i]);

         i++;

     }

    return 0;

}