免费注册 查看新帖 |

Chinaunix

  平台 论坛 博客 文库
最近访问板块 发新帖
查看: 1213 | 回复: 0
打印 上一主题 下一主题

Linux高级编程 - 进程(Processes) [复制链接]

论坛徽章:
0
跳转到指定楼层
1 [收藏(0)] [报告]
发表于 2009-01-04 10:35 |只看该作者 |倒序浏览
ALP(Advanced Linux Programming) Chapter 3 进程(Processes)
  • 什么叫进程?一个程序运行的一个实例称为一个进程(A RUNNING INSTANCE OF A PROGRAM IS CALLED A PROCESS)

[color="#0000ff"]3.1进程的基本操作
  • 进程的ID号
    • 每个进程有一个唯一的ID号,叫做pid(Process ID)。
    • 基本上每个进程都有一个父进程(单性繁殖),父进程的id是ppid (Parent Process ID)。当然也有例外,不然你告诉我最早的那个进程怎么来的?
    • ID号的类型是pid_t,pid和ppid可以分别通过系统函数getpid()和getppid()来得到。

  • ps命令可以输出当前活动的进程,这个命令为了和Unix的命令相匹配,有很多的options。例如-e表示输出所有,-u表示输出指定user的进程,等等。
  • 一个进程死了?无法退出了?如果你是windows用户,你一定会怀念Ctrl+Alt+Del。OK,其实在Linux下也很简单,用ps查到进程的PID,然后kill -9 PID,搞定。这里的9事实上是SIGKILL,也就是表示中止进程的signal。

[color="#0000ff"]3.2 进程的创建
  • 进程的创建有两种方法。第一种,简单!便宜没好货,所以这种方法也低效,不安全。第二种复杂,但是灵活度高,高效,还安全。
    • 第一种,system。system函数事实上只是创建一个当前shell的子进程,然后在shell中执行你指定的程序。所以它的安全度和灵活度都受到当前shell的限制。
    • 第二种,fork+exec的组合。fork的任务就是copy当前的进程,生成一个完全一样的进程。exec的任务就是执行你指定的程序,exec之前进程中的所有数据都被清空,就像一个全新的进程一样。

  • 进程调度,也就是哪个进程先执行,哪个进程后执行。在父进程和子进程直接没有必然的先后执行顺序。不过我们可以给进程指定优先级,优先级越高的越[color="#0000ff"]有可能先被执行(注意,是[color="#0000ff"]有可能,[color="#0000ff"]不是一定),所有进程的默认优先级都是0。
    • 用nice命令加上-n option来指定进程优先级。这里的option可以为负数,那意味着你降低了这个进程的优先级,降低优先级的操作需要有root权限。
    • 用renice命令给一个已经被nice过的进程重新指定优先级。

[color="#0000ff"]3.3 Signal
  • Signal是一种Unix的机制,可以给进程发送一个signal来达到通讯以及控制的目的。(本来想把signal翻成信号,可惜信号量这个词被OS里面的semaphore给占用了,为了避免混淆,干脆不翻了)
  • 我们可以把signal理解成为发送给进程的一个特别的消息,进程在收到signal之后,必须停下当前的代码马上处理之(类似于中断)。有三种处理方式:
    • 如果进程没有声明要处理该signal,则采取该signal的默认处理方式,通常是结束程序。
    • 进程可以声明忽略该signal(使用sigaction函数)
    • 进程可以声明处理该signal(使用sigaction函数),并提供一个signal处理函数。

  • 虽然非常非常少见,但是有可能程序在执行signal处理函数的时候被另一个signal所打断,因此signal处理函数必须是线程安全的。
  • Signal的例子:
    • SIGBUS:BUS出错
    • SIGSEGV:段错误(segmentation violation)
    • SIGPFE:浮点指针异常
    • SIGINT:中断signal,通常用户可以在程序执行过程中用Ctrl+C来向程序发送这个signal
    • SIGTERM:中止signal,通常结束一个程序,除非程序忽略该signal
    • SIGKILL:中止signal,总是结束一个程序,程序无法忽略该signal

[color="#0000ff"]3.4 进程的终结
  • 一个进程可以有很多钟终结的方式,例如正常终结,被上面提到的各种signal终结。我们可以用kill函数来给一个进程发送signal,如kill (child_pid, SIGTERM)。
  • 由于系统在调度父进程和子进程的时候没有一定的顺序,但有些时候父进程又需要等待子进程结束后再继续。怎么办?
    • 最简单的方法是使用wait函数,该函数会阻塞当前的进程,直到它的一个子进程结束(或者有错误发生)。
    • wait函数会返回子进程的exit code。
    • Linux还有其他更灵活的wait函数,例如waitpid,wait3,wait4等

  • 假设父进程没有调用wait等待子进程,但此时子进程已经结束了。由于子进程必须等待父进程来收集它的结束信息,因此它不能够就这么完全结束了,它成为了一种新的形态:僵尸进程(zombie process,这么翻觉得别扭,还是继续用zombie吧)
    • 在子进程成为zombie process后,如果父进程调用了wait,则子进程从zombie形态退出,完全结束。
    • 如果父进程没有调用wait而直接结束,则zombie子进程会被Init进程接管(就是那个pid为1的著名进程),Init将做为zombie子进程的新父进程,负责收尾工作,子进程结束。

  • 很显然,我想大部分的programmer都不想spawn一个子进程之后,父进程马上什么都不能做,只能傻傻的被阻塞在wait中等
    待子进程结束。万幸,我们可以通过signal来完成父进程对子进程的异步等待,子进程结束之后会向父进程发送一个SIGCHLD的signal,该
    signal的默认操作是什么事都不做,现在我们只需在这个signal的处理函数里面调用wait就万事大吉了。

               
               
               

本文来自ChinaUnix博客,如果查看原文请点:http://blog.chinaunix.net/u2/75758/showart_1772352.html
您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

北京盛拓优讯信息技术有限公司. 版权所有 京ICP备16024965号-6 北京市公安局海淀分局网监中心备案编号:11010802020122 niuxiaotong@pcpop.com 17352615567
未成年举报专区
中国互联网协会会员  联系我们:huangweiwei@itpub.net
感谢所有关心和支持过ChinaUnix的朋友们 转载本站内容请注明原作者名及出处

清除 Cookies - ChinaUnix - Archiver - WAP - TOP